137 static void set_serialized(const T* ptr) { |
146 static void set_serialized(const T* ptr) { |
138 assert(ptr != NULL, "invariant"); |
147 assert(ptr != NULL, "invariant"); |
139 SET_SERIALIZED(ptr); |
148 SET_SERIALIZED(ptr); |
140 assert(IS_SERIALIZED(ptr), "invariant"); |
149 assert(IS_SERIALIZED(ptr), "invariant"); |
141 } |
150 } |
|
151 |
|
152 template <typename T> |
|
153 void tag_leakp_artifact(T const& value) { |
|
154 assert(value != NULL, "invariant"); |
|
155 SET_LEAKP(value); |
|
156 assert(IS_LEAKP(value), "invariant"); |
|
157 } |
|
158 |
|
159 static void tag_leakp_klass_artifacts(KlassPtr k, bool class_unload) { |
|
160 assert(k != NULL, "invariant"); |
|
161 PkgPtr pkg = k->package(); |
|
162 if (pkg != NULL) { |
|
163 tag_leakp_artifact(pkg); |
|
164 ModPtr module = pkg->module(); |
|
165 if (module != NULL) { |
|
166 tag_leakp_artifact(module); |
|
167 } |
|
168 } |
|
169 CldPtr cld = k->class_loader_data(); |
|
170 assert(cld != NULL, "invariant"); |
|
171 if (!cld->is_unsafe_anonymous()) { |
|
172 tag_leakp_artifact(cld); |
|
173 } |
|
174 } |
|
175 |
|
176 class TagLeakpKlassArtifact { |
|
177 bool _class_unload; |
|
178 public: |
|
179 TagLeakpKlassArtifact(bool class_unload) : _class_unload(class_unload) {} |
|
180 bool operator()(KlassPtr klass) { |
|
181 if (IS_LEAKP(klass)) { |
|
182 tag_leakp_klass_artifacts(klass, _class_unload); |
|
183 } |
|
184 return true; |
|
185 } |
|
186 }; |
142 |
187 |
143 /* |
188 /* |
144 * In C++03, functions used as template parameters must have external linkage; |
189 * In C++03, functions used as template parameters must have external linkage; |
145 * this restriction was removed in C++11. Change back to "static" and |
190 * this restriction was removed in C++11. Change back to "static" and |
146 * rename functions when C++11 becomes available. |
191 * rename functions when C++11 becomes available. |
147 * |
192 * |
148 * The weird naming is an effort to decrease the risk of name clashes. |
193 * The weird naming is an effort to decrease the risk of name clashes. |
149 */ |
194 */ |
150 |
195 |
151 int write__klass(JfrCheckpointWriter* writer, const void* k) { |
196 static int write_klass(JfrCheckpointWriter* writer, KlassPtr klass, bool leakp) { |
152 assert(writer != NULL, "invariant"); |
197 assert(writer != NULL, "invariant"); |
153 assert(_artifacts != NULL, "invariant"); |
198 assert(_artifacts != NULL, "invariant"); |
154 assert(k != NULL, "invariant"); |
199 assert(klass != NULL, "invariant"); |
155 KlassPtr klass = (KlassPtr)k; |
|
156 traceid pkg_id = 0; |
200 traceid pkg_id = 0; |
157 KlassPtr theklass = klass; |
201 KlassPtr theklass = klass; |
158 if (theklass->is_objArray_klass()) { |
202 if (theklass->is_objArray_klass()) { |
159 const ObjArrayKlass* obj_arr_klass = ObjArrayKlass::cast(klass); |
203 const ObjArrayKlass* obj_arr_klass = ObjArrayKlass::cast(klass); |
160 theklass = obj_arr_klass->bottom_klass(); |
204 theklass = obj_arr_klass->bottom_klass(); |
163 pkg_id = package_id(theklass); |
207 pkg_id = package_id(theklass); |
164 } else { |
208 } else { |
165 assert(theklass->is_typeArray_klass(), "invariant"); |
209 assert(theklass->is_typeArray_klass(), "invariant"); |
166 } |
210 } |
167 writer->write(artifact_id(klass)); |
211 writer->write(artifact_id(klass)); |
168 writer->write(cld_id(klass->class_loader_data())); |
212 writer->write(cld_id(klass->class_loader_data(), leakp)); |
169 writer->write(mark_symbol(klass)); |
213 writer->write(mark_symbol(klass, leakp)); |
170 writer->write(pkg_id); |
214 writer->write(pkg_id); |
171 writer->write(get_flags(klass)); |
215 writer->write(get_flags(klass)); |
|
216 return 1; |
|
217 } |
|
218 |
|
219 int write__klass(JfrCheckpointWriter* writer, const void* k) { |
|
220 assert(k != NULL, "invariant"); |
|
221 KlassPtr klass = (KlassPtr)k; |
172 set_serialized(klass); |
222 set_serialized(klass); |
173 return 1; |
223 return write_klass(writer, klass, false); |
|
224 } |
|
225 |
|
226 int write__klass__leakp(JfrCheckpointWriter* writer, const void* k) { |
|
227 assert(k != NULL, "invariant"); |
|
228 KlassPtr klass = (KlassPtr)k; |
|
229 return write_klass(writer, klass, true); |
174 } |
230 } |
175 |
231 |
176 static void do_implied(Klass* klass) { |
232 static void do_implied(Klass* klass) { |
177 assert(klass != NULL, "invariant"); |
233 assert(klass != NULL, "invariant"); |
178 if (klass->is_subclass_of(SystemDictionary::ClassLoader_klass()) || klass == SystemDictionary::Object_klass()) { |
234 if (klass->is_subclass_of(SystemDictionary::ClassLoader_klass()) || klass == SystemDictionary::Object_klass()) { |
|
235 if (_leakp_writer != NULL) { |
|
236 SET_LEAKP(klass); |
|
237 } |
179 _subsystem_callback->do_artifact(klass); |
238 _subsystem_callback->do_artifact(klass); |
180 } |
239 } |
181 } |
240 } |
182 |
241 |
183 static void do_unloaded_klass(Klass* klass) { |
242 static void do_unloaded_klass(Klass* klass) { |
223 typedef JfrPredicatedTypeWriterImplHost<KlassPtr, KlassPredicate, write__klass> KlassWriterImpl; |
282 typedef JfrPredicatedTypeWriterImplHost<KlassPtr, KlassPredicate, write__klass> KlassWriterImpl; |
224 typedef JfrTypeWriterHost<KlassWriterImpl, TYPE_CLASS> KlassWriter; |
283 typedef JfrTypeWriterHost<KlassWriterImpl, TYPE_CLASS> KlassWriter; |
225 typedef CompositeFunctor<KlassPtr, KlassWriter, KlassArtifactRegistrator> KlassWriterRegistration; |
284 typedef CompositeFunctor<KlassPtr, KlassWriter, KlassArtifactRegistrator> KlassWriterRegistration; |
226 typedef JfrArtifactCallbackHost<KlassPtr, KlassWriterRegistration> KlassCallback; |
285 typedef JfrArtifactCallbackHost<KlassPtr, KlassWriterRegistration> KlassCallback; |
227 |
286 |
|
287 typedef LeakPredicate<KlassPtr> LeakKlassPredicate; |
|
288 typedef JfrPredicatedTypeWriterImplHost<KlassPtr, LeakKlassPredicate, write__klass__leakp> LeakKlassWriterImpl; |
|
289 typedef JfrTypeWriterHost<LeakKlassWriterImpl, TYPE_CLASS> LeakKlassWriter; |
|
290 typedef CompositeFunctor<KlassPtr, TagLeakpKlassArtifact, LeakKlassWriter> LeakpKlassArtifactTagging; |
|
291 |
|
292 typedef CompositeFunctor<KlassPtr, LeakpKlassArtifactTagging, KlassWriter> CompositeKlassWriter; |
|
293 typedef CompositeFunctor<KlassPtr, CompositeKlassWriter, KlassArtifactRegistrator> CompositeKlassWriterRegistration; |
|
294 typedef JfrArtifactCallbackHost<KlassPtr, CompositeKlassWriterRegistration> CompositeKlassCallback; |
|
295 |
228 static bool write_klasses() { |
296 static bool write_klasses() { |
229 assert(!_artifacts->has_klass_entries(), "invariant"); |
297 assert(!_artifacts->has_klass_entries(), "invariant"); |
230 assert(_writer != NULL, "invariant"); |
298 assert(_writer != NULL, "invariant"); |
231 KlassArtifactRegistrator reg(_artifacts); |
299 KlassArtifactRegistrator reg(_artifacts); |
232 KlassWriter kw(_writer, _class_unload); |
300 KlassWriter kw(_writer, _class_unload); |
233 KlassWriterRegistration kwr(&kw, ®); |
301 KlassWriterRegistration kwr(&kw, ®); |
234 KlassCallback callback(&kwr); |
302 if (_leakp_writer == NULL) { |
235 _subsystem_callback = &callback; |
303 KlassCallback callback(&kwr); |
236 do_klasses(); |
304 _subsystem_callback = &callback; |
|
305 do_klasses(); |
|
306 } else { |
|
307 TagLeakpKlassArtifact tagging(_class_unload); |
|
308 LeakKlassWriter lkw(_leakp_writer, _artifacts, _class_unload); |
|
309 LeakpKlassArtifactTagging lpkat(&tagging, &lkw); |
|
310 CompositeKlassWriter ckw(&lpkat, &kw); |
|
311 CompositeKlassWriterRegistration ckwr(&ckw, ®); |
|
312 CompositeKlassCallback callback(&ckwr); |
|
313 _subsystem_callback = &callback; |
|
314 do_klasses(); |
|
315 } |
237 if (is_complete()) { |
316 if (is_complete()) { |
238 return false; |
317 return false; |
239 } |
318 } |
240 _artifacts->tally(kw); |
319 _artifacts->tally(kw); |
241 return true; |
320 return true; |
254 CLEAR_SERIALIZED(value); |
333 CLEAR_SERIALIZED(value); |
255 } |
334 } |
256 assert(IS_NOT_SERIALIZED(value), "invariant"); |
335 assert(IS_NOT_SERIALIZED(value), "invariant"); |
257 } |
336 } |
258 |
337 |
259 int write__package(JfrCheckpointWriter* writer, const void* p) { |
338 static int write_package(JfrCheckpointWriter* writer, PkgPtr pkg, bool leakp) { |
260 assert(writer != NULL, "invariant"); |
339 assert(writer != NULL, "invariant"); |
261 assert(_artifacts != NULL, "invariant"); |
340 assert(_artifacts != NULL, "invariant"); |
|
341 assert(pkg != NULL, "invariant"); |
|
342 writer->write(artifact_id(pkg)); |
|
343 writer->write(mark_symbol(pkg->name(), leakp)); |
|
344 writer->write(module_id(pkg, leakp)); |
|
345 writer->write((bool)pkg->is_exported()); |
|
346 return 1; |
|
347 } |
|
348 |
|
349 int write__package(JfrCheckpointWriter* writer, const void* p) { |
262 assert(p != NULL, "invariant"); |
350 assert(p != NULL, "invariant"); |
263 PkgPtr pkg = (PkgPtr)p; |
351 PkgPtr pkg = (PkgPtr)p; |
264 writer->write(artifact_id(pkg)); |
|
265 writer->write(mark_symbol(pkg->name())); |
|
266 writer->write(module_id(pkg)); |
|
267 writer->write((bool)pkg->is_exported()); |
|
268 set_serialized(pkg); |
352 set_serialized(pkg); |
269 return 1; |
353 return write_package(writer, pkg, false); |
|
354 } |
|
355 |
|
356 int write__package__leakp(JfrCheckpointWriter* writer, const void* p) { |
|
357 assert(p != NULL, "invariant"); |
|
358 PkgPtr pkg = (PkgPtr)p; |
|
359 CLEAR_LEAKP(pkg); |
|
360 return write_package(writer, pkg, true); |
270 } |
361 } |
271 |
362 |
272 static void do_package(PackageEntry* entry) { |
363 static void do_package(PackageEntry* entry) { |
273 do_previous_epoch_artifact(_subsystem_callback, entry); |
364 do_previous_epoch_artifact(_subsystem_callback, entry); |
274 } |
365 } |
291 typedef JfrTypeWriterHost<PackageWriterImpl, TYPE_PACKAGE> PackageWriter; |
382 typedef JfrTypeWriterHost<PackageWriterImpl, TYPE_PACKAGE> PackageWriter; |
292 typedef CompositeFunctor<PkgPtr, PackageWriter, ClearArtifact<PkgPtr> > PackageWriterWithClear; |
383 typedef CompositeFunctor<PkgPtr, PackageWriter, ClearArtifact<PkgPtr> > PackageWriterWithClear; |
293 typedef KlassToFieldEnvelope<PackageFieldSelector, PackageWriter> KlassPackageWriter; |
384 typedef KlassToFieldEnvelope<PackageFieldSelector, PackageWriter> KlassPackageWriter; |
294 typedef JfrArtifactCallbackHost<PkgPtr, PackageWriterWithClear> PackageCallback; |
385 typedef JfrArtifactCallbackHost<PkgPtr, PackageWriterWithClear> PackageCallback; |
295 |
386 |
|
387 typedef LeakPredicate<PkgPtr> LeakPackagePredicate; |
|
388 typedef JfrPredicatedTypeWriterImplHost<PkgPtr, LeakPackagePredicate, write__package__leakp> LeakPackageWriterImpl; |
|
389 typedef JfrTypeWriterHost<LeakPackageWriterImpl, TYPE_PACKAGE> LeakPackageWriter; |
|
390 |
|
391 typedef CompositeFunctor<PkgPtr, LeakPackageWriter, PackageWriter> CompositePackageWriter; |
|
392 typedef KlassToFieldEnvelope<PackageFieldSelector, CompositePackageWriter> KlassCompositePackageWriter; |
|
393 typedef KlassToFieldEnvelope<PackageFieldSelector, PackageWriterWithClear> KlassPackageWriterWithClear; |
|
394 typedef CompositeFunctor<PkgPtr, CompositePackageWriter, ClearArtifact<PkgPtr> > CompositePackageWriterWithClear; |
|
395 typedef JfrArtifactCallbackHost<PkgPtr, CompositePackageWriterWithClear> CompositePackageCallback; |
|
396 |
296 static void write_packages() { |
397 static void write_packages() { |
297 assert(_writer != NULL, "invariant"); |
398 assert(_writer != NULL, "invariant"); |
298 PackageWriter pw(_writer, _class_unload); |
399 PackageWriter pw(_writer, _class_unload); |
299 KlassPackageWriter kpw(&pw); |
400 KlassPackageWriter kpw(&pw); |
300 _artifacts->iterate_klasses(kpw); |
401 if (current_epoch()) { |
301 if (previous_epoch()) { |
402 _artifacts->iterate_klasses(kpw); |
|
403 _artifacts->tally(pw); |
|
404 return; |
|
405 } |
|
406 assert(previous_epoch(), "invariant"); |
|
407 if (_leakp_writer == NULL) { |
|
408 _artifacts->iterate_klasses(kpw); |
302 ClearArtifact<PkgPtr> clear; |
409 ClearArtifact<PkgPtr> clear; |
303 PackageWriterWithClear pwwc(&pw, &clear); |
410 PackageWriterWithClear pwwc(&pw, &clear); |
304 PackageCallback callback(&pwwc); |
411 PackageCallback callback(&pwwc); |
305 _subsystem_callback = &callback; |
412 _subsystem_callback = &callback; |
306 do_packages(); |
413 do_packages(); |
|
414 } else { |
|
415 LeakPackageWriter lpw(_leakp_writer, _class_unload); |
|
416 CompositePackageWriter cpw(&lpw, &pw); |
|
417 KlassCompositePackageWriter kcpw(&cpw); |
|
418 _artifacts->iterate_klasses(kcpw); |
|
419 ClearArtifact<PkgPtr> clear; |
|
420 CompositePackageWriterWithClear cpwwc(&cpw, &clear); |
|
421 CompositePackageCallback callback(&cpwwc); |
|
422 _subsystem_callback = &callback; |
|
423 do_packages(); |
307 } |
424 } |
308 _artifacts->tally(pw); |
425 _artifacts->tally(pw); |
|
426 } |
|
427 |
|
428 static int write_module(JfrCheckpointWriter* writer, ModPtr mod, bool leakp) { |
|
429 assert(mod != NULL, "invariant"); |
|
430 assert(_artifacts != NULL, "invariant"); |
|
431 writer->write(artifact_id(mod)); |
|
432 writer->write(mark_symbol(mod->name(), leakp)); |
|
433 writer->write(mark_symbol(mod->version(), leakp)); |
|
434 writer->write(mark_symbol(mod->location(), leakp)); |
|
435 writer->write(cld_id(mod->loader_data(), leakp)); |
|
436 return 1; |
309 } |
437 } |
310 |
438 |
311 int write__module(JfrCheckpointWriter* writer, const void* m) { |
439 int write__module(JfrCheckpointWriter* writer, const void* m) { |
312 assert(m != NULL, "invariant"); |
440 assert(m != NULL, "invariant"); |
313 assert(_artifacts != NULL, "invariant"); |
|
314 ModPtr mod = (ModPtr)m; |
441 ModPtr mod = (ModPtr)m; |
315 writer->write(artifact_id(mod)); |
|
316 writer->write(mark_symbol(mod->name())); |
|
317 writer->write(mark_symbol(mod->version())); |
|
318 writer->write(mark_symbol(mod->location())); |
|
319 writer->write(cld_id(mod->loader_data())); |
|
320 set_serialized(mod); |
442 set_serialized(mod); |
321 return 1; |
443 return write_module(writer, mod, false); |
|
444 } |
|
445 |
|
446 int write__module__leakp(JfrCheckpointWriter* writer, const void* m) { |
|
447 assert(m != NULL, "invariant"); |
|
448 ModPtr mod = (ModPtr)m; |
|
449 CLEAR_LEAKP(mod); |
|
450 return write_module(writer, mod, true); |
322 } |
451 } |
323 |
452 |
324 static void do_module(ModuleEntry* entry) { |
453 static void do_module(ModuleEntry* entry) { |
325 do_previous_epoch_artifact(_subsystem_callback, entry); |
454 do_previous_epoch_artifact(_subsystem_callback, entry); |
326 } |
455 } |
344 typedef JfrTypeWriterHost<ModuleWriterImpl, TYPE_MODULE> ModuleWriter; |
473 typedef JfrTypeWriterHost<ModuleWriterImpl, TYPE_MODULE> ModuleWriter; |
345 typedef CompositeFunctor<ModPtr, ModuleWriter, ClearArtifact<ModPtr> > ModuleWriterWithClear; |
474 typedef CompositeFunctor<ModPtr, ModuleWriter, ClearArtifact<ModPtr> > ModuleWriterWithClear; |
346 typedef JfrArtifactCallbackHost<ModPtr, ModuleWriterWithClear> ModuleCallback; |
475 typedef JfrArtifactCallbackHost<ModPtr, ModuleWriterWithClear> ModuleCallback; |
347 typedef KlassToFieldEnvelope<ModuleFieldSelector, ModuleWriter> KlassModuleWriter; |
476 typedef KlassToFieldEnvelope<ModuleFieldSelector, ModuleWriter> KlassModuleWriter; |
348 |
477 |
|
478 typedef LeakPredicate<ModPtr> LeakModulePredicate; |
|
479 typedef JfrPredicatedTypeWriterImplHost<ModPtr, LeakModulePredicate, write__module__leakp> LeakModuleWriterImpl; |
|
480 typedef JfrTypeWriterHost<LeakModuleWriterImpl, TYPE_MODULE> LeakModuleWriter; |
|
481 |
|
482 typedef CompositeFunctor<ModPtr, LeakModuleWriter, ModuleWriter> CompositeModuleWriter; |
|
483 typedef KlassToFieldEnvelope<ModuleFieldSelector, CompositeModuleWriter> KlassCompositeModuleWriter; |
|
484 typedef CompositeFunctor<ModPtr, CompositeModuleWriter, ClearArtifact<ModPtr> > CompositeModuleWriterWithClear; |
|
485 typedef JfrArtifactCallbackHost<ModPtr, CompositeModuleWriterWithClear> CompositeModuleCallback; |
|
486 |
349 static void write_modules() { |
487 static void write_modules() { |
350 assert(_writer != NULL, "invariant"); |
488 assert(_writer != NULL, "invariant"); |
351 ModuleWriter mw(_writer, _class_unload); |
489 ModuleWriter mw(_writer, _class_unload); |
352 KlassModuleWriter kmw(&mw); |
490 KlassModuleWriter kmw(&mw); |
353 _artifacts->iterate_klasses(kmw); |
491 if (current_epoch()) { |
354 if (previous_epoch()) { |
492 _artifacts->iterate_klasses(kmw); |
|
493 _artifacts->tally(mw); |
|
494 return; |
|
495 } |
|
496 assert(previous_epoch(), "invariant"); |
|
497 if (_leakp_writer == NULL) { |
|
498 _artifacts->iterate_klasses(kmw); |
355 ClearArtifact<ModPtr> clear; |
499 ClearArtifact<ModPtr> clear; |
356 ModuleWriterWithClear mwwc(&mw, &clear); |
500 ModuleWriterWithClear mwwc(&mw, &clear); |
357 ModuleCallback callback(&mwwc); |
501 ModuleCallback callback(&mwwc); |
358 _subsystem_callback = &callback; |
502 _subsystem_callback = &callback; |
359 do_modules(); |
503 do_modules(); |
|
504 } else { |
|
505 LeakModuleWriter lmw(_leakp_writer, _class_unload); |
|
506 CompositeModuleWriter cmw(&lmw, &mw); |
|
507 KlassCompositeModuleWriter kcpw(&cmw); |
|
508 _artifacts->iterate_klasses(kcpw); |
|
509 ClearArtifact<ModPtr> clear; |
|
510 CompositeModuleWriterWithClear cmwwc(&cmw, &clear); |
|
511 CompositeModuleCallback callback(&cmwwc); |
|
512 _subsystem_callback = &callback; |
|
513 do_modules(); |
360 } |
514 } |
361 _artifacts->tally(mw); |
515 _artifacts->tally(mw); |
362 } |
516 } |
363 |
517 |
364 int write__classloader(JfrCheckpointWriter* writer, const void* c) { |
518 static int write_classloader(JfrCheckpointWriter* writer, CldPtr cld, bool leakp) { |
365 assert(c != NULL, "invariant"); |
519 assert(cld != NULL, "invariant"); |
366 CldPtr cld = (CldPtr)c; |
|
367 assert(!cld->is_unsafe_anonymous(), "invariant"); |
520 assert(!cld->is_unsafe_anonymous(), "invariant"); |
368 // class loader type |
521 // class loader type |
369 const Klass* class_loader_klass = cld->class_loader_klass(); |
522 const Klass* class_loader_klass = cld->class_loader_klass(); |
370 if (class_loader_klass == NULL) { |
523 if (class_loader_klass == NULL) { |
371 // (primordial) boot class loader |
524 // (primordial) boot class loader |
417 typedef JfrTypeWriterHost<CldWriterImpl, TYPE_CLASSLOADER> CldWriter; |
583 typedef JfrTypeWriterHost<CldWriterImpl, TYPE_CLASSLOADER> CldWriter; |
418 typedef CompositeFunctor<CldPtr, CldWriter, ClearArtifact<CldPtr> > CldWriterWithClear; |
584 typedef CompositeFunctor<CldPtr, CldWriter, ClearArtifact<CldPtr> > CldWriterWithClear; |
419 typedef JfrArtifactCallbackHost<CldPtr, CldWriterWithClear> CldCallback; |
585 typedef JfrArtifactCallbackHost<CldPtr, CldWriterWithClear> CldCallback; |
420 typedef KlassToFieldEnvelope<CldFieldSelector, CldWriter> KlassCldWriter; |
586 typedef KlassToFieldEnvelope<CldFieldSelector, CldWriter> KlassCldWriter; |
421 |
587 |
|
588 typedef LeakPredicate<CldPtr> LeakCldPredicate; |
|
589 typedef JfrPredicatedTypeWriterImplHost<CldPtr, LeakCldPredicate, write__classloader__leakp> LeakCldWriterImpl; |
|
590 typedef JfrTypeWriterHost<LeakCldWriterImpl, TYPE_CLASSLOADER> LeakCldWriter; |
|
591 |
|
592 typedef CompositeFunctor<CldPtr, LeakCldWriter, CldWriter> CompositeCldWriter; |
|
593 typedef KlassToFieldEnvelope<CldFieldSelector, CompositeCldWriter> KlassCompositeCldWriter; |
|
594 typedef CompositeFunctor<CldPtr, CompositeCldWriter, ClearArtifact<CldPtr> > CompositeCldWriterWithClear; |
|
595 typedef JfrArtifactCallbackHost<CldPtr, CompositeCldWriterWithClear> CompositeCldCallback; |
|
596 |
422 static void write_classloaders() { |
597 static void write_classloaders() { |
423 assert(_writer != NULL, "invariant"); |
598 assert(_writer != NULL, "invariant"); |
424 CldWriter cldw(_writer, _class_unload); |
599 CldWriter cldw(_writer, _class_unload); |
425 KlassCldWriter kcw(&cldw); |
600 KlassCldWriter kcw(&cldw); |
426 _artifacts->iterate_klasses(kcw); |
601 if (current_epoch()) { |
427 if (previous_epoch()) { |
602 _artifacts->iterate_klasses(kcw); |
|
603 _artifacts->tally(cldw); |
|
604 return; |
|
605 } |
|
606 assert(previous_epoch(), "invariant"); |
|
607 if (_leakp_writer == NULL) { |
|
608 _artifacts->iterate_klasses(kcw); |
428 ClearArtifact<CldPtr> clear; |
609 ClearArtifact<CldPtr> clear; |
429 CldWriterWithClear cldwwc(&cldw, &clear); |
610 CldWriterWithClear cldwwc(&cldw, &clear); |
430 CldCallback callback(&cldwwc); |
611 CldCallback callback(&cldwwc); |
431 _subsystem_callback = &callback; |
612 _subsystem_callback = &callback; |
432 do_class_loaders(); |
613 do_class_loaders(); |
|
614 } else { |
|
615 LeakCldWriter lcldw(_leakp_writer, _class_unload); |
|
616 CompositeCldWriter ccldw(&lcldw, &cldw); |
|
617 KlassCompositeCldWriter kccldw(&ccldw); |
|
618 _artifacts->iterate_klasses(kccldw); |
|
619 ClearArtifact<CldPtr> clear; |
|
620 CompositeCldWriterWithClear ccldwwc(&ccldw, &clear); |
|
621 CompositeCldCallback callback(&ccldwwc); |
|
622 _subsystem_callback = &callback; |
|
623 do_class_loaders(); |
433 } |
624 } |
434 _artifacts->tally(cldw); |
625 _artifacts->tally(cldw); |
435 } |
626 } |
436 |
627 |
437 static u1 get_visibility(MethodPtr method) { |
628 static u1 get_visibility(MethodPtr method) { |
444 assert(method != NULL, "invariant"); |
635 assert(method != NULL, "invariant"); |
445 SET_METHOD_SERIALIZED(method); |
636 SET_METHOD_SERIALIZED(method); |
446 assert(IS_METHOD_SERIALIZED(method), "invariant"); |
637 assert(IS_METHOD_SERIALIZED(method), "invariant"); |
447 } |
638 } |
448 |
639 |
|
640 static int write_method(JfrCheckpointWriter* writer, MethodPtr method, bool leakp) { |
|
641 assert(writer != NULL, "invariant"); |
|
642 assert(method != NULL, "invariant"); |
|
643 assert(_artifacts != NULL, "invariant"); |
|
644 KlassPtr klass = method->method_holder(); |
|
645 assert(klass != NULL, "invariant"); |
|
646 writer->write(method_id(klass, method)); |
|
647 writer->write(artifact_id(klass)); |
|
648 writer->write(mark_symbol(method->name(), leakp)); |
|
649 writer->write(mark_symbol(method->signature(), leakp)); |
|
650 writer->write((u2)get_flags(method)); |
|
651 writer->write(get_visibility(method)); |
|
652 return 1; |
|
653 } |
|
654 |
449 int write__method(JfrCheckpointWriter* writer, const void* m) { |
655 int write__method(JfrCheckpointWriter* writer, const void* m) { |
450 assert(writer != NULL, "invariant"); |
|
451 assert(_artifacts != NULL, "invariant"); |
|
452 assert(m != NULL, "invariant"); |
656 assert(m != NULL, "invariant"); |
453 MethodPtr method = (MethodPtr)m; |
657 MethodPtr method = (MethodPtr)m; |
454 KlassPtr klass = method->method_holder(); |
|
455 assert(klass != NULL, "invariant"); |
|
456 assert(METHOD_USED_ANY_EPOCH(klass), "invariant"); |
|
457 writer->write(method_id(klass, method)); |
|
458 writer->write(artifact_id(klass)); |
|
459 writer->write(mark_symbol(method->name())); |
|
460 writer->write(mark_symbol(method->signature())); |
|
461 writer->write((u2)get_flags(method)); |
|
462 writer->write(get_visibility(method)); |
|
463 set_serialized(method); |
658 set_serialized(method); |
464 return 1; |
659 return write_method(writer, method, false); |
465 } |
660 } |
466 |
661 |
467 template <typename MethodCallback, typename KlassCallback> |
662 int write__method__leakp(JfrCheckpointWriter* writer, const void* m) { |
|
663 assert(m != NULL, "invariant"); |
|
664 MethodPtr method = (MethodPtr)m; |
|
665 return write_method(writer, method, true); |
|
666 } |
|
667 |
|
668 template <typename MethodCallback, typename KlassCallback, bool leakp> |
468 class MethodIteratorHost { |
669 class MethodIteratorHost { |
469 private: |
670 private: |
470 MethodCallback _method_cb; |
671 MethodCallback _method_cb; |
471 KlassCallback _klass_cb; |
672 KlassCallback _klass_cb; |
472 MethodUsedPredicate _method_used_predicate; |
673 MethodUsedPredicate<leakp> _method_used_predicate; |
473 MethodFlagPredicate _method_flag_predicate; |
674 MethodFlagPredicate<leakp> _method_flag_predicate; |
474 public: |
675 public: |
475 MethodIteratorHost(JfrCheckpointWriter* writer, |
676 MethodIteratorHost(JfrCheckpointWriter* writer, |
476 bool current_epoch = false, |
677 bool current_epoch = false, |
477 bool class_unload = false, |
678 bool class_unload = false, |
478 bool skip_header = false) : |
679 bool skip_header = false) : |
510 } |
710 } |
511 }; |
711 }; |
512 |
712 |
513 typedef SerializePredicate<MethodPtr> MethodPredicate; |
713 typedef SerializePredicate<MethodPtr> MethodPredicate; |
514 typedef JfrPredicatedTypeWriterImplHost<MethodPtr, MethodPredicate, write__method> MethodWriterImplTarget; |
714 typedef JfrPredicatedTypeWriterImplHost<MethodPtr, MethodPredicate, write__method> MethodWriterImplTarget; |
|
715 typedef Wrapper<KlassPtr, Stub> KlassCallbackStub; |
515 typedef JfrTypeWriterHost<MethodWriterImplTarget, TYPE_METHOD> MethodWriterImpl; |
716 typedef JfrTypeWriterHost<MethodWriterImplTarget, TYPE_METHOD> MethodWriterImpl; |
516 typedef Wrapper<KlassPtr, Stub> KlassCallbackStub; |
717 typedef MethodIteratorHost<MethodWriterImpl, KlassCallbackStub, false> MethodWriter; |
517 typedef MethodIteratorHost<MethodWriterImpl, KlassCallbackStub> MethodWriter; |
718 |
|
719 typedef LeakPredicate<MethodPtr> LeakMethodPredicate; |
|
720 typedef JfrPredicatedTypeWriterImplHost<MethodPtr, LeakMethodPredicate, write__method__leakp> LeakMethodWriterImplTarget; |
|
721 typedef JfrTypeWriterHost<LeakMethodWriterImplTarget, TYPE_METHOD> LeakMethodWriterImpl; |
|
722 typedef MethodIteratorHost<LeakMethodWriterImpl, KlassCallbackStub, true> LeakMethodWriter; |
|
723 typedef CompositeFunctor<KlassPtr, LeakMethodWriter, MethodWriter> CompositeMethodWriter; |
518 |
724 |
519 static void write_methods() { |
725 static void write_methods() { |
520 assert(_writer != NULL, "invariant"); |
726 assert(_writer != NULL, "invariant"); |
521 MethodWriter mw(_writer, current_epoch(), _class_unload); |
727 MethodWriter mw(_writer, current_epoch(), _class_unload); |
522 _artifacts->iterate_klasses(mw); |
728 if (_leakp_writer == NULL) { |
|
729 _artifacts->iterate_klasses(mw); |
|
730 } else { |
|
731 LeakMethodWriter lpmw(_leakp_writer, current_epoch(), _class_unload); |
|
732 CompositeMethodWriter cmw(&lpmw, &mw); |
|
733 _artifacts->iterate_klasses(cmw); |
|
734 } |
523 _artifacts->tally(mw); |
735 _artifacts->tally(mw); |
524 } |
736 } |
525 |
737 |
526 template <> |
738 template <> |
527 void set_serialized<JfrSymbolId::SymbolEntry>(SymbolEntryPtr ptr) { |
739 void set_serialized<JfrSymbolId::SymbolEntry>(SymbolEntryPtr ptr) { |
535 assert(ptr != NULL, "invariant"); |
747 assert(ptr != NULL, "invariant"); |
536 ptr->set_serialized(); |
748 ptr->set_serialized(); |
537 assert(ptr->is_serialized(), "invariant"); |
749 assert(ptr->is_serialized(), "invariant"); |
538 } |
750 } |
539 |
751 |
540 int write__symbol(JfrCheckpointWriter* writer, const void* e) { |
752 static int write_symbol(JfrCheckpointWriter* writer, SymbolEntryPtr entry, bool leakp) { |
541 assert(writer != NULL, "invariant"); |
753 assert(writer != NULL, "invariant"); |
542 assert(e != NULL, "invariant"); |
754 assert(entry != NULL, "invariant"); |
543 ResourceMark rm; |
755 ResourceMark rm; |
544 SymbolEntryPtr entry = (SymbolEntryPtr)e; |
|
545 writer->write(create_symbol_id(entry->id())); |
756 writer->write(create_symbol_id(entry->id())); |
546 writer->write(entry->value()->as_C_string()); |
757 writer->write(entry->value()->as_C_string()); |
|
758 return 1; |
|
759 } |
|
760 |
|
761 int write__symbol(JfrCheckpointWriter* writer, const void* e) { |
|
762 assert(e != NULL, "invariant"); |
|
763 SymbolEntryPtr entry = (SymbolEntryPtr)e; |
547 set_serialized(entry); |
764 set_serialized(entry); |
|
765 return write_symbol(writer, entry, false); |
|
766 } |
|
767 |
|
768 int write__symbol__leakp(JfrCheckpointWriter* writer, const void* e) { |
|
769 assert(e != NULL, "invariant"); |
|
770 SymbolEntryPtr entry = (SymbolEntryPtr)e; |
|
771 return write_symbol(writer, entry, true); |
|
772 } |
|
773 |
|
774 static int write_cstring(JfrCheckpointWriter* writer, CStringEntryPtr entry, bool leakp) { |
|
775 assert(writer != NULL, "invariant"); |
|
776 assert(entry != NULL, "invariant"); |
|
777 writer->write(create_symbol_id(entry->id())); |
|
778 writer->write(entry->value()); |
548 return 1; |
779 return 1; |
549 } |
780 } |
550 |
781 |
551 int write__cstring(JfrCheckpointWriter* writer, const void* e) { |
782 int write__cstring(JfrCheckpointWriter* writer, const void* e) { |
552 assert(writer != NULL, "invariant"); |
|
553 assert(e != NULL, "invariant"); |
783 assert(e != NULL, "invariant"); |
554 CStringEntryPtr entry = (CStringEntryPtr)e; |
784 CStringEntryPtr entry = (CStringEntryPtr)e; |
555 writer->write(create_symbol_id(entry->id())); |
|
556 writer->write(entry->value()); |
|
557 set_serialized(entry); |
785 set_serialized(entry); |
558 return 1; |
786 return write_cstring(writer, entry, false); |
559 } |
787 } |
560 |
788 |
561 typedef SymbolPredicate<SymbolEntryPtr> SymPredicate; |
789 int write__cstring__leakp(JfrCheckpointWriter* writer, const void* e) { |
|
790 assert(e != NULL, "invariant"); |
|
791 CStringEntryPtr entry = (CStringEntryPtr)e; |
|
792 return write_cstring(writer, entry, true); |
|
793 } |
|
794 |
|
795 typedef SymbolPredicate<SymbolEntryPtr, false> SymPredicate; |
562 typedef JfrPredicatedTypeWriterImplHost<SymbolEntryPtr, SymPredicate, write__symbol> SymbolEntryWriterImpl; |
796 typedef JfrPredicatedTypeWriterImplHost<SymbolEntryPtr, SymPredicate, write__symbol> SymbolEntryWriterImpl; |
563 typedef JfrTypeWriterHost<SymbolEntryWriterImpl, TYPE_SYMBOL> SymbolEntryWriter; |
797 typedef JfrTypeWriterHost<SymbolEntryWriterImpl, TYPE_SYMBOL> SymbolEntryWriter; |
564 typedef SymbolPredicate<CStringEntryPtr> CStringPredicate; |
798 typedef SymbolPredicate<CStringEntryPtr, false> CStringPredicate; |
565 typedef JfrPredicatedTypeWriterImplHost<CStringEntryPtr, CStringPredicate, write__cstring> CStringEntryWriterImpl; |
799 typedef JfrPredicatedTypeWriterImplHost<CStringEntryPtr, CStringPredicate, write__cstring> CStringEntryWriterImpl; |
566 typedef JfrTypeWriterHost<CStringEntryWriterImpl, TYPE_SYMBOL> CStringEntryWriter; |
800 typedef JfrTypeWriterHost<CStringEntryWriterImpl, TYPE_SYMBOL> CStringEntryWriter; |
567 |
801 |
|
802 typedef SymbolPredicate<SymbolEntryPtr, true> LeakSymPredicate; |
|
803 typedef JfrPredicatedTypeWriterImplHost<SymbolEntryPtr, LeakSymPredicate, write__symbol__leakp> LeakSymbolEntryWriterImpl; |
|
804 typedef JfrTypeWriterHost<LeakSymbolEntryWriterImpl, TYPE_SYMBOL> LeakSymbolEntryWriter; |
|
805 typedef CompositeFunctor<SymbolEntryPtr, LeakSymbolEntryWriter, SymbolEntryWriter> CompositeSymbolWriter; |
|
806 typedef SymbolPredicate<CStringEntryPtr, true> LeakCStringPredicate; |
|
807 typedef JfrPredicatedTypeWriterImplHost<CStringEntryPtr, LeakCStringPredicate, write__cstring__leakp> LeakCStringEntryWriterImpl; |
|
808 typedef JfrTypeWriterHost<LeakCStringEntryWriterImpl, TYPE_SYMBOL> LeakCStringEntryWriter; |
|
809 typedef CompositeFunctor<CStringEntryPtr, LeakCStringEntryWriter, CStringEntryWriter> CompositeCStringWriter; |
|
810 |
|
811 static void write_symbols_with_leakp() { |
|
812 assert(_leakp_writer != NULL, "invariant"); |
|
813 SymbolEntryWriter sw(_writer, _class_unload); |
|
814 LeakSymbolEntryWriter lsw(_leakp_writer, _class_unload); |
|
815 CompositeSymbolWriter csw(&lsw, &sw); |
|
816 _artifacts->iterate_symbols(csw); |
|
817 CStringEntryWriter ccsw(_writer, _class_unload, true); // skip header |
|
818 LeakCStringEntryWriter lccsw(_leakp_writer, _class_unload, true); // skip header |
|
819 CompositeCStringWriter cccsw(&lccsw, &ccsw); |
|
820 _artifacts->iterate_cstrings(cccsw); |
|
821 sw.add(ccsw.count()); |
|
822 lsw.add(lccsw.count()); |
|
823 _artifacts->tally(sw); |
|
824 } |
|
825 |
568 static void write_symbols() { |
826 static void write_symbols() { |
569 assert(_writer != NULL, "invariant"); |
827 assert(_writer != NULL, "invariant"); |
570 SymbolEntryWriter symbol_writer(_writer, _class_unload); |
828 if (_leakp_writer != NULL) { |
571 _artifacts->iterate_symbols(symbol_writer); |
829 write_symbols_with_leakp(); |
572 CStringEntryWriter cstring_writer(_writer, _class_unload, true); // skip header |
830 return; |
573 _artifacts->iterate_cstrings(cstring_writer); |
831 } |
574 symbol_writer.add(cstring_writer.count()); |
832 SymbolEntryWriter sw(_writer, _class_unload); |
575 _artifacts->tally(symbol_writer); |
833 _artifacts->iterate_symbols(sw); |
|
834 CStringEntryWriter csw(_writer, _class_unload, true); // skip header |
|
835 _artifacts->iterate_cstrings(csw); |
|
836 sw.add(csw.count()); |
|
837 _artifacts->tally(sw); |
576 } |
838 } |
577 |
839 |
578 typedef Wrapper<KlassPtr, ClearArtifact> ClearKlassBits; |
840 typedef Wrapper<KlassPtr, ClearArtifact> ClearKlassBits; |
579 typedef Wrapper<MethodPtr, ClearArtifact> ClearMethodFlag; |
841 typedef Wrapper<MethodPtr, ClearArtifact> ClearMethodFlag; |
580 typedef MethodIteratorHost<ClearMethodFlag, ClearKlassBits> ClearKlassAndMethods; |
842 typedef MethodIteratorHost<ClearMethodFlag, ClearKlassBits, false> ClearKlassAndMethods; |
581 |
843 |
582 static size_t teardown() { |
844 static size_t teardown() { |
583 assert(_artifacts != NULL, "invariant"); |
845 assert(_artifacts != NULL, "invariant"); |
584 const size_t total_count = _artifacts->total_count(); |
846 const size_t total_count = _artifacts->total_count(); |
585 if (previous_epoch()) { |
847 if (previous_epoch()) { |