src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp
branchJEP-349-branch
changeset 57983 a57907813a83
parent 57870 00860d9caf4d
child 57991 a101d496334a
equal deleted inserted replaced
57971:aa7b1ea52413 57983:a57907813a83
    63 static traceid create_symbol_id(traceid artifact_id) {
    63 static traceid create_symbol_id(traceid artifact_id) {
    64   return artifact_id != 0 ? CREATE_SYMBOL_ID(artifact_id) : 0;
    64   return artifact_id != 0 ? CREATE_SYMBOL_ID(artifact_id) : 0;
    65 }
    65 }
    66 
    66 
    67 static JfrCheckpointWriter* _writer = NULL;
    67 static JfrCheckpointWriter* _writer = NULL;
       
    68 static JfrCheckpointWriter* _leakp_writer = NULL;
    68 static bool _class_unload = false;
    69 static bool _class_unload = false;
    69 static bool _flushpoint = false;
    70 static bool _flushpoint = false;
    70 static JfrArtifactSet* _artifacts = NULL;
    71 static JfrArtifactSet* _artifacts = NULL;
    71 static JfrArtifactClosure* _subsystem_callback = NULL;
    72 static JfrArtifactClosure* _subsystem_callback = NULL;
    72 
    73 
    80 
    81 
    81 static bool is_complete() {
    82 static bool is_complete() {
    82   return !_artifacts->has_klass_entries() && current_epoch();
    83   return !_artifacts->has_klass_entries() && current_epoch();
    83 }
    84 }
    84 
    85 
    85 static traceid mark_symbol(KlassPtr klass) {
    86 static traceid mark_symbol(KlassPtr klass, bool leakp) {
    86   return klass != NULL ? create_symbol_id(_artifacts->mark(klass)) : 0;
    87   return klass != NULL ? create_symbol_id(_artifacts->mark(klass, leakp)) : 0;
    87 }
    88 }
    88 
    89 
    89 static traceid mark_symbol(Symbol* symbol) {
    90 static traceid mark_symbol(Symbol* symbol, bool leakp) {
    90   return symbol != NULL ? create_symbol_id(_artifacts->mark(symbol)) : 0;
    91   return symbol != NULL ? create_symbol_id(_artifacts->mark(symbol, leakp)) : 0;
    91 }
    92 }
    92 
    93 
    93 template <typename T>
    94 template <typename T>
    94 static traceid artifact_id(const T* ptr) {
    95 static traceid artifact_id(const T* ptr) {
    95   assert(ptr != NULL, "invariant");
    96   assert(ptr != NULL, "invariant");
   100   assert(klass != NULL, "invariant");
   101   assert(klass != NULL, "invariant");
   101   PkgPtr pkg_entry = klass->package();
   102   PkgPtr pkg_entry = klass->package();
   102   return pkg_entry != NULL ? artifact_id(pkg_entry) : 0;
   103   return pkg_entry != NULL ? artifact_id(pkg_entry) : 0;
   103 }
   104 }
   104 
   105 
   105 static traceid module_id(PkgPtr pkg) {
   106 static traceid module_id(PkgPtr pkg, bool leakp) {
   106   assert(pkg != NULL, "invariant");
   107   assert(pkg != NULL, "invariant");
   107   ModPtr module_entry = pkg->module();
   108   ModPtr module_entry = pkg->module();
   108   if (module_entry != NULL && module_entry->is_named()) {
   109   if (module_entry != NULL && module_entry->is_named()) {
   109     SET_TRANSIENT(module_entry);
   110     if (leakp) {
       
   111       SET_LEAKP(module_entry);
       
   112     } else {
       
   113       SET_TRANSIENT(module_entry);
       
   114     }
   110     return artifact_id(module_entry);
   115     return artifact_id(module_entry);
   111   }
   116   }
   112   return 0;
   117   return 0;
   113 }
   118 }
   114 
   119 
   116   assert(klass != NULL, "invariant");
   121   assert(klass != NULL, "invariant");
   117   assert(method != NULL, "invariant");
   122   assert(method != NULL, "invariant");
   118   return METHOD_ID(klass, method);
   123   return METHOD_ID(klass, method);
   119 }
   124 }
   120 
   125 
   121 static traceid cld_id(CldPtr cld) {
   126 static traceid cld_id(CldPtr cld, bool leakp) {
   122   assert(cld != NULL, "invariant");
   127   assert(cld != NULL, "invariant");
   123   if (cld->is_unsafe_anonymous()) {
   128   if (cld->is_unsafe_anonymous()) {
   124     return 0;
   129     return 0;
   125   }
   130   }
   126   SET_TRANSIENT(cld);
   131   if (leakp) {
       
   132     SET_LEAKP(cld);
       
   133   } else {
       
   134     SET_TRANSIENT(cld);
       
   135   }
   127   return artifact_id(cld);
   136   return artifact_id(cld);
   128 }
   137 }
   129 
   138 
   130 template <typename T>
   139 template <typename T>
   131 static s4 get_flags(const T* ptr) {
   140 static s4 get_flags(const T* ptr) {
   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, &reg);
   301   KlassWriterRegistration kwr(&kw, &reg);
   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, &reg);
       
   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
   373     writer->write((traceid)0);  // class loader type id (absence of)
   526     writer->write((traceid)0);  // class loader type id (absence of)
   374     writer->write(create_symbol_id(1)); // 1 maps to synthetic name -> "bootstrap"
   527     writer->write(create_symbol_id(1)); // 1 maps to synthetic name -> "bootstrap"
   375   } else {
   528   } else {
   376     writer->write(artifact_id(cld)); // class loader instance id
   529     writer->write(artifact_id(cld)); // class loader instance id
   377     writer->write(artifact_id(class_loader_klass)); // class loader type id
   530     writer->write(artifact_id(class_loader_klass)); // class loader type id
   378     writer->write(mark_symbol(cld->name())); // class loader instance name
   531     writer->write(mark_symbol(cld->name(), leakp)); // class loader instance name
   379   }
   532   }
       
   533   return 1;
       
   534 }
       
   535 
       
   536 int write__classloader(JfrCheckpointWriter* writer, const void* c) {
       
   537   assert(c != NULL, "invariant");
       
   538   CldPtr cld = (CldPtr)c;
   380   set_serialized(cld);
   539   set_serialized(cld);
   381   return 1;
   540   return write_classloader(writer, cld, false);
       
   541 }
       
   542 
       
   543 int write__classloader__leakp(JfrCheckpointWriter* writer, const void* c) {
       
   544   assert(c != NULL, "invariant");
       
   545   CldPtr cld = (CldPtr)c;
       
   546   CLEAR_LEAKP(cld);
       
   547   return write_classloader(writer, cld, true);
   382 }
   548 }
   383 
   549 
   384 static void do_class_loader_data(ClassLoaderData* cld) {
   550 static void do_class_loader_data(ClassLoaderData* cld) {
   385   do_previous_epoch_artifact(_subsystem_callback, cld);
   551   do_previous_epoch_artifact(_subsystem_callback, cld);
   386 }
   552 }
   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) :
   481     _method_used_predicate(current_epoch),
   682     _method_used_predicate(current_epoch),
   482     _method_flag_predicate(current_epoch) {}
   683     _method_flag_predicate(current_epoch) {}
   483 
   684 
   484   bool operator()(KlassPtr klass) {
   685   bool operator()(KlassPtr klass) {
   485     if (_method_used_predicate(klass)) {
   686     if (_method_used_predicate(klass)) {
   486       assert(METHOD_AND_CLASS_USED_ANY_EPOCH(klass), "invariant");
       
   487       const InstanceKlass* const ik = InstanceKlass::cast(klass);
   687       const InstanceKlass* const ik = InstanceKlass::cast(klass);
   488       const int len = ik->methods()->length();
   688       const int len = ik->methods()->length();
   489       for (int i = 0; i < len; ++i) {
   689       for (int i = 0; i < len; ++i) {
   490         MethodPtr method = ik->methods()->at(i);
   690         MethodPtr method = ik->methods()->at(i);
   491         if (_method_flag_predicate(method)) {
   691         if (_method_flag_predicate(method)) {
   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()) {
   590     ++checkpoint_id;
   852     ++checkpoint_id;
   591   }
   853   }
   592   return total_count;
   854   return total_count;
   593 }
   855 }
   594 
   856 
   595 static void setup(JfrCheckpointWriter* writer, bool class_unload, bool flushpoint) {
   857 static void setup(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer, bool class_unload, bool flushpoint) {
   596   _writer = writer;
   858   _writer = writer;
       
   859   _leakp_writer = leakp_writer;
   597   _class_unload = class_unload;
   860   _class_unload = class_unload;
   598   _flushpoint = flushpoint;
   861   _flushpoint = flushpoint;
   599   if (_artifacts == NULL) {
   862   if (_artifacts == NULL) {
   600     _artifacts = new JfrArtifactSet(class_unload);
   863     _artifacts = new JfrArtifactSet(class_unload);
   601   } else {
   864   } else {
   606 }
   869 }
   607 
   870 
   608 /**
   871 /**
   609  * Write all "tagged" (in-use) constant artifacts and their dependencies.
   872  * Write all "tagged" (in-use) constant artifacts and their dependencies.
   610  */
   873  */
   611 size_t JfrTypeSet::serialize(JfrCheckpointWriter* writer, bool class_unload, bool flushpoint) {
   874 size_t JfrTypeSet::serialize(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer, bool class_unload, bool flushpoint) {
   612   assert(writer != NULL, "invariant");
   875   assert(writer != NULL, "invariant");
   613   ResourceMark rm;
   876   ResourceMark rm;
   614   setup(writer, class_unload, flushpoint);
   877   setup(writer, leakp_writer, class_unload, flushpoint);
   615   // write order is important because an individual write step
   878   // write order is important because an individual write step
   616   // might tag an artifact to be written in a subsequent step
   879   // might tag an artifact to be written in a subsequent step
   617   if (!write_klasses()) {
   880   if (!write_klasses()) {
   618     return 0;
   881     return 0;
   619   }
   882   }