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

changeset 9885
8e875c964f41
parent 9858
b985cbb00e68
equal deleted inserted replaced
9884:1258121876f8 9885:8e875c964f41
179 int count() const { 179 int count() const {
180 return _count; 180 return _count;
181 } 181 }
182 }; 182 };
183 183
184 void ObjectSampleCheckpoint::install(JfrCheckpointWriter& writer, bool class_unload, bool resume) { 184 void ObjectSampleCheckpoint::install(JfrCheckpointWriter& writer, bool class_unload, bool type_set) {
185 assert(class_unload ? SafepointSynchronize::is_at_safepoint() : LeakProfiler::is_suspended(), "invariant");
186
187 if (!writer.has_data()) { 185 if (!writer.has_data()) {
188 if (!class_unload) {
189 LeakProfiler::resume();
190 }
191 assert(LeakProfiler::is_running(), "invariant");
192 return; 186 return;
193 } 187 }
194 188
195 assert(writer.has_data(), "invariant"); 189 assert(writer.has_data(), "invariant");
196 const JfrCheckpointBlobHandle h_cp = writer.checkpoint_blob(); 190 const JfrCheckpointBlobHandle h_cp = writer.checkpoint_blob();
197 191 CheckpointInstall install(h_cp);
198 const ObjectSampler* const object_sampler = LeakProfiler::object_sampler(); 192
193 // Class unload implies a safepoint.
194 // Not class unload implies the object sampler is locked, because it was claimed exclusively earlier.
195 // Therefore: direct access the object sampler instance is safe.
196 ObjectSampler* const object_sampler = ObjectSampler::sampler();
199 assert(object_sampler != NULL, "invariant"); 197 assert(object_sampler != NULL, "invariant");
200 198
201 ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last()); 199 ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
202 const ObjectSample* const last_resolved = object_sampler->last_resolved(); 200 const ObjectSample* const last_resolved = object_sampler->last_resolved();
203 CheckpointInstall install(h_cp); 201
204 202 // install only to new samples since last resolved checkpoint
205 if (class_unload) {
206 if (last != NULL) {
207 // all samples need the class unload information
208 do_samples(last, NULL, install);
209 }
210 assert(LeakProfiler::is_running(), "invariant");
211 return;
212 }
213
214 // only new samples since last resolved checkpoint
215 if (last != last_resolved) { 203 if (last != last_resolved) {
216 do_samples(last, last_resolved, install); 204 do_samples(last, last_resolved, install);
217 if (resume) { 205 if (class_unload) {
218 const_cast<ObjectSampler*>(object_sampler)->set_last_resolved(last); 206 return;
219 } 207 }
220 } 208 if (type_set) {
221 assert(LeakProfiler::is_suspended(), "invariant"); 209 object_sampler->set_last_resolved(last);
222 if (resume) { 210 }
223 LeakProfiler::resume(); 211 }
224 assert(LeakProfiler::is_running(), "invariant"); 212 }
225 } 213
226 } 214 void ObjectSampleCheckpoint::write(ObjectSampler* sampler, EdgeStore* edge_store, bool emit_all, Thread* thread) {
227 215 assert(sampler != NULL, "invariant");
228 void ObjectSampleCheckpoint::write(const EdgeStore* edge_store, bool emit_all, Thread* thread) {
229 assert(edge_store != NULL, "invariant"); 216 assert(edge_store != NULL, "invariant");
230 assert(thread != NULL, "invariant"); 217 assert(thread != NULL, "invariant");
218
231 static bool types_registered = false; 219 static bool types_registered = false;
232 if (!types_registered) { 220 if (!types_registered) {
233 JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTSYSTEM, false, true, new RootSystemType()); 221 JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTSYSTEM, false, true, new RootSystemType());
234 JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTTYPE, false, true, new RootType()); 222 JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTTYPE, false, true, new RootType());
235 types_registered = true; 223 types_registered = true;
236 } 224 }
237 const ObjectSampler* const object_sampler = LeakProfiler::object_sampler(); 225
238 assert(object_sampler != NULL, "invariant"); 226 const jlong last_sweep = emit_all ? max_jlong : sampler->last_sweep().value();
239 const jlong last_sweep = emit_all ? max_jlong : object_sampler->last_sweep().value(); 227 ObjectSample* const last = const_cast<ObjectSample*>(sampler->last());
240 ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
241 { 228 {
242 JfrCheckpointWriter writer(false, false, thread); 229 JfrCheckpointWriter writer(false, false, thread);
243 CheckpointWrite checkpoint_write(writer, last_sweep); 230 CheckpointWrite checkpoint_write(writer, last_sweep);
244 do_samples(last, NULL, checkpoint_write); 231 do_samples(last, NULL, checkpoint_write);
245 } 232 }
233
246 CheckpointStateReset state_reset(last_sweep); 234 CheckpointStateReset state_reset(last_sweep);
247 do_samples(last, NULL, state_reset); 235 do_samples(last, NULL, state_reset);
236
248 if (!edge_store->is_empty()) { 237 if (!edge_store->is_empty()) {
249 // java object and chain representations 238 // java object and chain representations
250 JfrCheckpointWriter writer(false, true, thread); 239 JfrCheckpointWriter writer(false, true, thread);
251 ObjectSampleWriter osw(writer, edge_store); 240 ObjectSampleWriter osw(writer, edge_store);
252 edge_store->iterate_edges(osw); 241 edge_store->iterate(osw);
253 } 242 }
254 } 243 }
255 244
256 WriteObjectSampleStacktrace::WriteObjectSampleStacktrace(JfrStackTraceRepository& repo) : 245 int ObjectSampleCheckpoint::mark(ObjectSampler* object_sampler, ObjectSampleMarker& marker, bool emit_all) {
257 _stack_trace_repo(repo) { 246 assert(object_sampler != NULL, "invariant");
258 } 247 ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
248 if (last == NULL) {
249 return 0;
250 }
251 const jlong last_sweep = emit_all ? max_jlong : object_sampler->last_sweep().value();
252 SampleMark mark(marker, last_sweep);
253 do_samples(last, NULL, mark);
254 return mark.count();
255 }
256
257 WriteObjectSampleStacktrace::WriteObjectSampleStacktrace(ObjectSampler* sampler, JfrStackTraceRepository& repo) :
258 _sampler(sampler), _stack_trace_repo(repo) {}
259 259
260 bool WriteObjectSampleStacktrace::process() { 260 bool WriteObjectSampleStacktrace::process() {
261 assert(SafepointSynchronize::is_at_safepoint(), "invariant"); 261 assert(LeakProfiler::is_running(), "invariant");
262 if (!LeakProfiler::is_running()) { 262 assert(_sampler != NULL, "invariant");
263 return true; 263
264 } 264 ObjectSample* const last = const_cast<ObjectSample*>(_sampler->last());
265 // Suspend the LeakProfiler subsystem 265 const ObjectSample* const last_resolved = _sampler->last_resolved();
266 // to ensure stable samples even
267 // after we return from the safepoint.
268 LeakProfiler::suspend();
269 assert(!LeakProfiler::is_running(), "invariant");
270 assert(LeakProfiler::is_suspended(), "invariant");
271
272 const ObjectSampler* object_sampler = LeakProfiler::object_sampler();
273 assert(object_sampler != NULL, "invariant");
274 assert(LeakProfiler::is_suspended(), "invariant");
275
276 ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
277 const ObjectSample* const last_resolved = object_sampler->last_resolved();
278 if (last == last_resolved) { 266 if (last == last_resolved) {
279 assert(LeakProfiler::is_suspended(), "invariant");
280 return true; 267 return true;
281 } 268 }
282 269
283 JfrCheckpointWriter writer(false, true, Thread::current()); 270 JfrCheckpointWriter writer(false, true, Thread::current());
284 const JfrCheckpointContext ctx = writer.context(); 271 const JfrCheckpointContext ctx = writer.context();
292 do_samples(last, last_resolved, stack_trace_write); 279 do_samples(last, last_resolved, stack_trace_write);
293 count = stack_trace_write.count(); 280 count = stack_trace_write.count();
294 } 281 }
295 if (count == 0) { 282 if (count == 0) {
296 writer.set_context(ctx); 283 writer.set_context(ctx);
297 assert(LeakProfiler::is_suspended(), "invariant");
298 return true; 284 return true;
299 } 285 }
300 assert(count > 0, "invariant"); 286 assert(count > 0, "invariant");
301 writer.write_count((u4)count, count_offset); 287 writer.write_count((u4)count, count_offset);
302 JfrStackTraceRepository::write_metadata(writer); 288 JfrStackTraceRepository::write_metadata(writer);
303 289
290 // install the stacktrace checkpoint information to the candidates
304 ObjectSampleCheckpoint::install(writer, false, false); 291 ObjectSampleCheckpoint::install(writer, false, false);
305 assert(LeakProfiler::is_suspended(), "invariant");
306 return true; 292 return true;
307 } 293 }
308
309 int ObjectSampleCheckpoint::mark(ObjectSampleMarker& marker, bool emit_all) {
310 const ObjectSampler* object_sampler = LeakProfiler::object_sampler();
311 assert(object_sampler != NULL, "invariant");
312 ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
313 if (last == NULL) {
314 return 0;
315 }
316 const jlong last_sweep = emit_all ? max_jlong : object_sampler->last_sweep().value();
317 SampleMark mark(marker, last_sweep);
318 do_samples(last, NULL, mark);
319 return mark.count();
320 }

mercurial