1 /*
   2  * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/classLoaderDataGraph.hpp"
  27 #include "classfile/javaClasses.inline.hpp"
  28 #include "classfile/moduleEntry.hpp"
  29 #include "classfile/packageEntry.hpp"
  30 #include "classfile/symbolTable.hpp"
  31 #include "jfr/jfr.hpp"
  32 #include "jfr/jni/jfrGetAllEventClasses.hpp"
  33 #include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp"
  34 #include "jfr/recorder/checkpoint/types/jfrTypeSet.hpp"
  35 #include "jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp"
  36 #include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
  37 #include "jfr/utilities/jfrHashtable.hpp"
  38 #include "jfr/utilities/jfrTypes.hpp"
  39 #include "jfr/writers/jfrTypeWriterHost.hpp"
  40 #include "memory/iterator.hpp"
  41 #include "memory/resourceArea.hpp"
  42 #include "oops/instanceKlass.hpp"
  43 #include "oops/objArrayKlass.hpp"
  44 #include "oops/oop.inline.hpp"
  45 #include "utilities/accessFlags.hpp"
  46 #include "utilities/bitMap.inline.hpp"
  47 
  48 typedef const Klass* KlassPtr;
  49 typedef const PackageEntry* PkgPtr;
  50 typedef const ModuleEntry* ModPtr;
  51 typedef const ClassLoaderData* CldPtr;
  52 typedef const Method* MethodPtr;
  53 typedef const Symbol* SymbolPtr;
  54 typedef const JfrSymbolId::SymbolEntry* SymbolEntryPtr;
  55 typedef const JfrSymbolId::CStringEntry* CStringEntryPtr;
  56 
  57 static JfrCheckpointWriter* _writer = NULL;
  58 static JfrCheckpointWriter* _leakp_writer = NULL;
  59 static JfrArtifactSet* _artifacts = NULL;
  60 static JfrArtifactClosure* _subsystem_callback = NULL;
  61 static bool _class_unload = false;
  62 static bool _flushpoint = false;
  63 
  64 // incremented on each rotation
  65 static u8 checkpoint_id = 1;
  66 
  67 // creates a unique id by combining a checkpoint relative symbol id (2^24)
  68 // with the current checkpoint id (2^40)
  69 #define CREATE_SYMBOL_ID(sym_id) (((u8)((checkpoint_id << 24) | sym_id)))
  70 
  71 static traceid create_symbol_id(traceid artifact_id) {
  72   return artifact_id != 0 ? CREATE_SYMBOL_ID(artifact_id) : 0;
  73 }
  74 
  75 static bool current_epoch() {
  76   return _class_unload || _flushpoint;
  77 }
  78 
  79 static bool previous_epoch() {
  80   return !current_epoch();
  81 }
  82 
  83 static bool is_complete() {
  84   return !_artifacts->has_klass_entries() && current_epoch();
  85 }
  86 
  87 static traceid mark_symbol(KlassPtr klass, bool leakp) {
  88   return klass != NULL ? create_symbol_id(_artifacts->mark(klass, leakp)) : 0;
  89 }
  90 
  91 static traceid mark_symbol(Symbol* symbol, bool leakp) {
  92   return symbol != NULL ? create_symbol_id(_artifacts->mark(symbol, leakp)) : 0;
  93 }
  94 
  95 static traceid get_bootstrap_name(bool leakp) {
  96   return create_symbol_id(_artifacts->bootstrap_name(leakp));
  97 }
  98 
  99 template <typename T>
 100 static traceid artifact_id(const T* ptr) {
 101   assert(ptr != NULL, "invariant");
 102   return TRACE_ID(ptr);
 103 }
 104 
 105 static traceid package_id(KlassPtr klass, bool leakp) {
 106   assert(klass != NULL, "invariant");
 107   PkgPtr pkg_entry = klass->package();
 108   if (pkg_entry == NULL) {
 109     return 0;
 110   }
 111   if (leakp) {
 112     SET_LEAKP(pkg_entry);
 113   }
 114   // package implicitly tagged already
 115   return artifact_id(pkg_entry);
 116 }
 117 
 118 static traceid module_id(PkgPtr pkg, bool leakp) {
 119   assert(pkg != NULL, "invariant");
 120   ModPtr module_entry = pkg->module();
 121   if (module_entry == NULL) {
 122     return 0;
 123   }
 124   if (leakp) {
 125     SET_LEAKP(module_entry);
 126   } else {
 127     SET_TRANSIENT(module_entry);
 128   }
 129   return artifact_id(module_entry);
 130 }
 131 
 132 static traceid method_id(KlassPtr klass, MethodPtr method) {
 133   assert(klass != NULL, "invariant");
 134   assert(method != NULL, "invariant");
 135   return METHOD_ID(klass, method);
 136 }
 137 
 138 static traceid cld_id(CldPtr cld, bool leakp) {
 139   assert(cld != NULL, "invariant");
 140   if (leakp) {
 141     SET_LEAKP(cld);
 142   } else {
 143     SET_TRANSIENT(cld);
 144   }
 145   return artifact_id(cld);
 146 }
 147 
 148 template <typename T>
 149 static s4 get_flags(const T* ptr) {
 150   assert(ptr != NULL, "invariant");
 151   return ptr->access_flags().get_flags();
 152 }
 153 
 154 static bool is_unsafe_anonymous(const Klass* klass) {
 155   assert(klass != NULL, "invariant");
 156   return klass->is_instance_klass() && ((const InstanceKlass*)klass)->is_unsafe_anonymous();
 157 }
 158 
 159 static ClassLoaderData* get_cld(const Klass* klass) {
 160   assert(klass != NULL, "invariant");
 161   return is_unsafe_anonymous(klass) ?
 162     InstanceKlass::cast(klass)->unsafe_anonymous_host()->class_loader_data() : klass->class_loader_data();
 163 }
 164 
 165 template <typename T>
 166 static void set_serialized(const T* ptr) {
 167   assert(ptr != NULL, "invariant");
 168   SET_SERIALIZED(ptr);
 169   assert(IS_SERIALIZED(ptr), "invariant");
 170 }
 171 
 172 /*
 173  * In C++03, functions used as template parameters must have external linkage;
 174  * this restriction was removed in C++11. Change back to "static" and
 175  * rename functions when C++11 becomes available.
 176  *
 177  * The weird naming is an effort to decrease the risk of name clashes.
 178  */
 179 
 180 static int write_klass(JfrCheckpointWriter* writer, KlassPtr klass, bool leakp) {
 181   assert(writer != NULL, "invariant");
 182   assert(_artifacts != NULL, "invariant");
 183   assert(klass != NULL, "invariant");
 184   traceid pkg_id = 0;
 185   KlassPtr theklass = klass;
 186   if (theklass->is_objArray_klass()) {
 187     const ObjArrayKlass* obj_arr_klass = ObjArrayKlass::cast(klass);
 188     theklass = obj_arr_klass->bottom_klass();
 189   }
 190   if (theklass->is_instance_klass()) {
 191     pkg_id = package_id(theklass, leakp);
 192   } else {
 193     assert(theklass->is_typeArray_klass(), "invariant");
 194   }
 195   writer->write(artifact_id(klass));
 196   writer->write(cld_id(get_cld(klass), leakp));
 197   writer->write(mark_symbol(klass, leakp));
 198   writer->write(pkg_id);
 199   writer->write(get_flags(klass));
 200   return 1;
 201 }
 202 
 203 int write__klass(JfrCheckpointWriter* writer, const void* k) {
 204   assert(k != NULL, "invariant");
 205   KlassPtr klass = (KlassPtr)k;
 206   set_serialized(klass);
 207   return write_klass(writer, klass, false);
 208 }
 209 
 210 int write__klass__leakp(JfrCheckpointWriter* writer, const void* k) {
 211   assert(k != NULL, "invariant");
 212   KlassPtr klass = (KlassPtr)k;
 213   return write_klass(writer, klass, true);
 214 }
 215 
 216 static bool is_implied(const Klass* klass) {
 217   assert(klass != NULL, "invariant");
 218   return klass->is_subclass_of(SystemDictionary::ClassLoader_klass()) || klass == SystemDictionary::Object_klass();
 219 }
 220 
 221 static void do_implied(Klass* klass) {
 222   assert(klass != NULL, "invariant");
 223   if (is_implied(klass)) {
 224     if (_leakp_writer != NULL) {
 225       SET_LEAKP(klass);
 226     }
 227     _subsystem_callback->do_artifact(klass);
 228   }
 229 }
 230 
 231 static void do_unloaded_klass(Klass* klass) {
 232   assert(klass != NULL, "invariant");
 233   assert(_subsystem_callback != NULL, "invariant");
 234   if (IS_JDK_JFR_EVENT_SUBKLASS(klass)) {
 235     JfrEventClasses::increment_unloaded_event_class();
 236   }
 237   if (USED_THIS_EPOCH(klass)) {
 238     ObjectSampleCheckpoint::on_klass_unload(klass);
 239     _subsystem_callback->do_artifact(klass);
 240     return;
 241   }
 242   do_implied(klass);
 243 }
 244 
 245 static void do_klass(Klass* klass) {
 246   assert(klass != NULL, "invariant");
 247   assert(_subsystem_callback != NULL, "invariant");
 248   if (_flushpoint) {
 249     if (USED_THIS_EPOCH(klass)) {
 250       _subsystem_callback->do_artifact(klass);
 251       return;
 252     }
 253   } else {
 254     if (USED_PREV_EPOCH(klass)) {
 255       _subsystem_callback->do_artifact(klass);
 256       return;
 257     }
 258   }
 259   do_implied(klass);
 260 }
 261 
 262 static void do_klasses() {
 263   if (_class_unload) {
 264     ClassLoaderDataGraph::classes_unloading_do(&do_unloaded_klass);
 265     return;
 266   }
 267   ClassLoaderDataGraph::classes_do(&do_klass);
 268 }
 269 
 270 typedef SerializePredicate<KlassPtr> KlassPredicate;
 271 typedef JfrPredicatedTypeWriterImplHost<KlassPtr, KlassPredicate, write__klass> KlassWriterImpl;
 272 typedef JfrTypeWriterHost<KlassWriterImpl, TYPE_CLASS> KlassWriter;
 273 typedef CompositeFunctor<KlassPtr, KlassWriter, KlassArtifactRegistrator> KlassWriterRegistration;
 274 typedef JfrArtifactCallbackHost<KlassPtr, KlassWriterRegistration> KlassCallback;
 275 
 276 template <>
 277 class LeakPredicate<const Klass*> {
 278 public:
 279   LeakPredicate(bool class_unload) {}
 280   bool operator()(const Klass* klass) {
 281     assert(klass != NULL, "invariant");
 282     return IS_LEAKP(klass) || is_implied(klass);
 283   }
 284 };
 285 
 286 typedef LeakPredicate<KlassPtr> LeakKlassPredicate;
 287 typedef JfrPredicatedTypeWriterImplHost<KlassPtr, LeakKlassPredicate, write__klass__leakp> LeakKlassWriterImpl;
 288 typedef JfrTypeWriterHost<LeakKlassWriterImpl, TYPE_CLASS> LeakKlassWriter;
 289 
 290 typedef CompositeFunctor<KlassPtr, LeakKlassWriter, KlassWriter> CompositeKlassWriter;
 291 typedef CompositeFunctor<KlassPtr, CompositeKlassWriter, KlassArtifactRegistrator> CompositeKlassWriterRegistration;
 292 typedef JfrArtifactCallbackHost<KlassPtr, CompositeKlassWriterRegistration> CompositeKlassCallback;
 293 
 294 static bool write_klasses() {
 295   assert(!_artifacts->has_klass_entries(), "invariant");
 296   assert(_writer != NULL, "invariant");
 297   KlassArtifactRegistrator reg(_artifacts);
 298   KlassWriter kw(_writer, _class_unload);
 299   KlassWriterRegistration kwr(&kw, &reg);
 300   if (_leakp_writer == NULL) {
 301     KlassCallback callback(&kwr);
 302     _subsystem_callback = &callback;
 303     do_klasses();
 304   } else {
 305     LeakKlassWriter lkw(_leakp_writer, _artifacts, _class_unload);
 306     CompositeKlassWriter ckw(&lkw, &kw);
 307     CompositeKlassWriterRegistration ckwr(&ckw, &reg);
 308     CompositeKlassCallback callback(&ckwr);
 309     _subsystem_callback = &callback;
 310     do_klasses();
 311   }
 312   if (is_complete()) {
 313     return false;
 314   }
 315   _artifacts->tally(kw);
 316   return true;
 317 }
 318 
 319 template <typename T>
 320 static void do_previous_epoch_artifact(JfrArtifactClosure* callback, T* value) {
 321   assert(callback != NULL, "invariant");
 322   assert(value != NULL, "invariant");
 323   if (USED_PREV_EPOCH(value)) {
 324     callback->do_artifact(value);
 325     assert(IS_NOT_SERIALIZED(value), "invariant");
 326     return;
 327   }
 328   if (IS_SERIALIZED(value)) {
 329     CLEAR_SERIALIZED(value);
 330   }
 331   assert(IS_NOT_SERIALIZED(value), "invariant");
 332 }
 333 
 334 static int write_package(JfrCheckpointWriter* writer, PkgPtr pkg, bool leakp) {
 335   assert(writer != NULL, "invariant");
 336   assert(_artifacts != NULL, "invariant");
 337   assert(pkg != NULL, "invariant");
 338   writer->write(artifact_id(pkg));
 339   writer->write(mark_symbol(pkg->name(), leakp));
 340   writer->write(module_id(pkg, leakp));
 341   writer->write((bool)pkg->is_exported());
 342   return 1;
 343 }
 344 
 345 int write__package(JfrCheckpointWriter* writer, const void* p) {
 346   assert(p != NULL, "invariant");
 347   PkgPtr pkg = (PkgPtr)p;
 348   set_serialized(pkg);
 349   return write_package(writer, pkg, false);
 350 }
 351 
 352 int write__package__leakp(JfrCheckpointWriter* writer, const void* p) {
 353   assert(p != NULL, "invariant");
 354   PkgPtr pkg = (PkgPtr)p;
 355   CLEAR_LEAKP(pkg);
 356   return write_package(writer, pkg, true);
 357 }
 358 
 359 static void do_package(PackageEntry* entry) {
 360   do_previous_epoch_artifact(_subsystem_callback, entry);
 361 }
 362 
 363 static void do_packages() {
 364   ClassLoaderDataGraph::packages_do(&do_package);
 365 }
 366 
 367 class PackageFieldSelector {
 368  public:
 369   typedef PkgPtr TypePtr;
 370   static TypePtr select(KlassPtr klass) {
 371     assert(klass != NULL, "invariant");
 372     return ((InstanceKlass*)klass)->package();
 373   }
 374 };
 375 
 376 typedef SerializePredicate<PkgPtr> PackagePredicate;
 377 typedef JfrPredicatedTypeWriterImplHost<PkgPtr, PackagePredicate, write__package> PackageWriterImpl;
 378 typedef JfrTypeWriterHost<PackageWriterImpl, TYPE_PACKAGE> PackageWriter;
 379 typedef CompositeFunctor<PkgPtr, PackageWriter, ClearArtifact<PkgPtr> > PackageWriterWithClear;
 380 typedef KlassToFieldEnvelope<PackageFieldSelector, PackageWriter> KlassPackageWriter;
 381 typedef JfrArtifactCallbackHost<PkgPtr, PackageWriterWithClear> PackageCallback;
 382 
 383 typedef LeakPredicate<PkgPtr> LeakPackagePredicate;
 384 typedef JfrPredicatedTypeWriterImplHost<PkgPtr, LeakPackagePredicate, write__package__leakp> LeakPackageWriterImpl;
 385 typedef JfrTypeWriterHost<LeakPackageWriterImpl, TYPE_PACKAGE> LeakPackageWriter;
 386 
 387 typedef CompositeFunctor<PkgPtr, LeakPackageWriter, PackageWriter> CompositePackageWriter;
 388 typedef KlassToFieldEnvelope<PackageFieldSelector, CompositePackageWriter> KlassCompositePackageWriter;
 389 typedef KlassToFieldEnvelope<PackageFieldSelector, PackageWriterWithClear> KlassPackageWriterWithClear;
 390 typedef CompositeFunctor<PkgPtr, CompositePackageWriter, ClearArtifact<PkgPtr> > CompositePackageWriterWithClear;
 391 typedef JfrArtifactCallbackHost<PkgPtr, CompositePackageWriterWithClear> CompositePackageCallback;
 392 
 393 static void write_packages() {
 394   assert(_writer != NULL, "invariant");
 395   PackageWriter pw(_writer, _class_unload);
 396   KlassPackageWriter kpw(&pw);
 397   if (current_epoch()) {
 398     _artifacts->iterate_klasses(kpw);
 399     _artifacts->tally(pw);
 400     return;
 401   }
 402   assert(previous_epoch(), "invariant");
 403   if (_leakp_writer == NULL) {
 404     _artifacts->iterate_klasses(kpw);
 405     ClearArtifact<PkgPtr> clear;
 406     PackageWriterWithClear pwwc(&pw, &clear);
 407     PackageCallback callback(&pwwc);
 408     _subsystem_callback = &callback;
 409     do_packages();
 410   } else {
 411     LeakPackageWriter lpw(_leakp_writer, _class_unload);
 412     CompositePackageWriter cpw(&lpw, &pw);
 413     KlassCompositePackageWriter kcpw(&cpw);
 414     _artifacts->iterate_klasses(kcpw);
 415     ClearArtifact<PkgPtr> clear;
 416     CompositePackageWriterWithClear cpwwc(&cpw, &clear);
 417     CompositePackageCallback callback(&cpwwc);
 418     _subsystem_callback = &callback;
 419     do_packages();
 420   }
 421   _artifacts->tally(pw);
 422 }
 423 
 424 static int write_module(JfrCheckpointWriter* writer, ModPtr mod, bool leakp) {
 425   assert(mod != NULL, "invariant");
 426   assert(_artifacts != NULL, "invariant");
 427   writer->write(artifact_id(mod));
 428   writer->write(mark_symbol(mod->name(), leakp));
 429   writer->write(mark_symbol(mod->version(), leakp));
 430   writer->write(mark_symbol(mod->location(), leakp));
 431   writer->write(cld_id(mod->loader_data(), leakp));
 432   return 1;
 433 }
 434 
 435 int write__module(JfrCheckpointWriter* writer, const void* m) {
 436   assert(m != NULL, "invariant");
 437   ModPtr mod = (ModPtr)m;
 438   set_serialized(mod);
 439   return write_module(writer, mod, false);
 440 }
 441 
 442 int write__module__leakp(JfrCheckpointWriter* writer, const void* m) {
 443   assert(m != NULL, "invariant");
 444   ModPtr mod = (ModPtr)m;
 445   CLEAR_LEAKP(mod);
 446   return write_module(writer, mod, true);
 447 }
 448 
 449 static void do_module(ModuleEntry* entry) {
 450   do_previous_epoch_artifact(_subsystem_callback, entry);
 451 }
 452 
 453 static void do_modules() {
 454   ClassLoaderDataGraph::modules_do(&do_module);
 455 }
 456 
 457 class ModuleFieldSelector {
 458  public:
 459   typedef ModPtr TypePtr;
 460   static TypePtr select(KlassPtr klass) {
 461     assert(klass != NULL, "invariant");
 462     PkgPtr pkg = klass->package();
 463     return pkg != NULL ? pkg->module() : NULL;
 464   }
 465 };
 466 
 467 typedef SerializePredicate<ModPtr> ModulePredicate;
 468 typedef JfrPredicatedTypeWriterImplHost<ModPtr, ModulePredicate, write__module> ModuleWriterImpl;
 469 typedef JfrTypeWriterHost<ModuleWriterImpl, TYPE_MODULE> ModuleWriter;
 470 typedef CompositeFunctor<ModPtr, ModuleWriter, ClearArtifact<ModPtr> > ModuleWriterWithClear;
 471 typedef JfrArtifactCallbackHost<ModPtr, ModuleWriterWithClear> ModuleCallback;
 472 typedef KlassToFieldEnvelope<ModuleFieldSelector, ModuleWriter> KlassModuleWriter;
 473 
 474 typedef LeakPredicate<ModPtr> LeakModulePredicate;
 475 typedef JfrPredicatedTypeWriterImplHost<ModPtr, LeakModulePredicate, write__module__leakp> LeakModuleWriterImpl;
 476 typedef JfrTypeWriterHost<LeakModuleWriterImpl, TYPE_MODULE> LeakModuleWriter;
 477 
 478 typedef CompositeFunctor<ModPtr, LeakModuleWriter, ModuleWriter> CompositeModuleWriter;
 479 typedef KlassToFieldEnvelope<ModuleFieldSelector, CompositeModuleWriter> KlassCompositeModuleWriter;
 480 typedef CompositeFunctor<ModPtr, CompositeModuleWriter, ClearArtifact<ModPtr> > CompositeModuleWriterWithClear;
 481 typedef JfrArtifactCallbackHost<ModPtr, CompositeModuleWriterWithClear> CompositeModuleCallback;
 482 
 483 static void write_modules() {
 484   assert(_writer != NULL, "invariant");
 485   ModuleWriter mw(_writer, _class_unload);
 486   KlassModuleWriter kmw(&mw);
 487   if (current_epoch()) {
 488     _artifacts->iterate_klasses(kmw);
 489     _artifacts->tally(mw);
 490     return;
 491   }
 492   assert(previous_epoch(), "invariant");
 493   if (_leakp_writer == NULL) {
 494     _artifacts->iterate_klasses(kmw);
 495     ClearArtifact<ModPtr> clear;
 496     ModuleWriterWithClear mwwc(&mw, &clear);
 497     ModuleCallback callback(&mwwc);
 498     _subsystem_callback = &callback;
 499     do_modules();
 500   } else {
 501     LeakModuleWriter lmw(_leakp_writer, _class_unload);
 502     CompositeModuleWriter cmw(&lmw, &mw);
 503     KlassCompositeModuleWriter kcpw(&cmw);
 504     _artifacts->iterate_klasses(kcpw);
 505     ClearArtifact<ModPtr> clear;
 506     CompositeModuleWriterWithClear cmwwc(&cmw, &clear);
 507     CompositeModuleCallback callback(&cmwwc);
 508     _subsystem_callback = &callback;
 509     do_modules();
 510   }
 511   _artifacts->tally(mw);
 512 }
 513 
 514 static int write_classloader(JfrCheckpointWriter* writer, CldPtr cld, bool leakp) {
 515   assert(cld != NULL, "invariant");
 516   // class loader type
 517   const Klass* class_loader_klass = cld->class_loader_klass();
 518   if (class_loader_klass == NULL) {
 519     // (primordial) boot class loader
 520     writer->write(artifact_id(cld)); // class loader instance id
 521     writer->write((traceid)0);  // class loader type id (absence of)
 522     writer->write(get_bootstrap_name(leakp)); // maps to synthetic name -> "bootstrap"
 523   } else {
 524     writer->write(artifact_id(cld)); // class loader instance id
 525     writer->write(artifact_id(class_loader_klass)); // class loader type id
 526     writer->write(mark_symbol(cld->name(), leakp)); // class loader instance name
 527   }
 528   return 1;
 529 }
 530 
 531 int write__classloader(JfrCheckpointWriter* writer, const void* c) {
 532   assert(c != NULL, "invariant");
 533   CldPtr cld = (CldPtr)c;
 534   set_serialized(cld);
 535   return write_classloader(writer, cld, false);
 536 }
 537 
 538 int write__classloader__leakp(JfrCheckpointWriter* writer, const void* c) {
 539   assert(c != NULL, "invariant");
 540   CldPtr cld = (CldPtr)c;
 541   CLEAR_LEAKP(cld);
 542   return write_classloader(writer, cld, true);
 543 }
 544 
 545 static void do_class_loader_data(ClassLoaderData* cld) {
 546   do_previous_epoch_artifact(_subsystem_callback, cld);
 547 }
 548 
 549 class KlassCldFieldSelector {
 550  public:
 551   typedef CldPtr TypePtr;
 552   static TypePtr select(KlassPtr klass) {
 553     assert(klass != NULL, "invariant");
 554     return get_cld(klass);
 555   }
 556 };
 557 
 558 class ModuleCldFieldSelector {
 559 public:
 560   typedef CldPtr TypePtr;
 561   static TypePtr select(KlassPtr klass) {
 562     assert(klass != NULL, "invariant");
 563     ModPtr mod = ModuleFieldSelector::select(klass);
 564     return mod != NULL ? mod->loader_data() : NULL;
 565   }
 566 };
 567 
 568 class CLDCallback : public CLDClosure {
 569  public:
 570   CLDCallback() {}
 571   void do_cld(ClassLoaderData* cld) {
 572     assert(cld != NULL, "invariant");
 573     if (cld->is_shortlived()) {
 574       return;
 575     }
 576     do_class_loader_data(cld);
 577   }
 578 };
 579 
 580 static void do_class_loaders() {
 581   CLDCallback cld_cb;
 582   ClassLoaderDataGraph::loaded_cld_do(&cld_cb);
 583 }
 584 
 585 typedef SerializePredicate<CldPtr> CldPredicate;
 586 typedef JfrPredicatedTypeWriterImplHost<CldPtr, CldPredicate, write__classloader> CldWriterImpl;
 587 typedef JfrTypeWriterHost<CldWriterImpl, TYPE_CLASSLOADER> CldWriter;
 588 typedef CompositeFunctor<CldPtr, CldWriter, ClearArtifact<CldPtr> > CldWriterWithClear;
 589 typedef JfrArtifactCallbackHost<CldPtr, CldWriterWithClear> CldCallback;
 590 typedef KlassToFieldEnvelope<KlassCldFieldSelector, CldWriter> KlassCldWriter;
 591 typedef KlassToFieldEnvelope<ModuleCldFieldSelector, CldWriter> ModuleCldWriter;
 592 typedef CompositeFunctor<KlassPtr, KlassCldWriter, ModuleCldWriter> KlassAndModuleCldWriter;
 593 
 594 typedef LeakPredicate<CldPtr> LeakCldPredicate;
 595 typedef JfrPredicatedTypeWriterImplHost<CldPtr, LeakCldPredicate, write__classloader__leakp> LeakCldWriterImpl;
 596 typedef JfrTypeWriterHost<LeakCldWriterImpl, TYPE_CLASSLOADER> LeakCldWriter;
 597 
 598 typedef CompositeFunctor<CldPtr, LeakCldWriter, CldWriter> CompositeCldWriter;
 599 typedef KlassToFieldEnvelope<KlassCldFieldSelector, CompositeCldWriter> KlassCompositeCldWriter;
 600 typedef KlassToFieldEnvelope<ModuleCldFieldSelector, CompositeCldWriter> ModuleCompositeCldWriter;
 601 typedef CompositeFunctor<KlassPtr, KlassCompositeCldWriter, ModuleCompositeCldWriter> KlassAndModuleCompositeCldWriter;
 602 typedef CompositeFunctor<CldPtr, CompositeCldWriter, ClearArtifact<CldPtr> > CompositeCldWriterWithClear;
 603 typedef JfrArtifactCallbackHost<CldPtr, CompositeCldWriterWithClear> CompositeCldCallback;
 604 
 605 static void write_classloaders() {
 606   assert(_writer != NULL, "invariant");
 607   CldWriter cldw(_writer, _class_unload);
 608   KlassCldWriter kcw(&cldw);
 609   ModuleCldWriter mcw(&cldw);
 610   KlassAndModuleCldWriter kmcw(&kcw, &mcw);
 611   if (current_epoch()) {
 612     _artifacts->iterate_klasses(kmcw);
 613     _artifacts->tally(cldw);
 614     return;
 615   }
 616   assert(previous_epoch(), "invariant");
 617   if (_leakp_writer == NULL) {
 618     _artifacts->iterate_klasses(kmcw);
 619     ClearArtifact<CldPtr> clear;
 620     CldWriterWithClear cldwwc(&cldw, &clear);
 621     CldCallback callback(&cldwwc);
 622     _subsystem_callback = &callback;
 623     do_class_loaders();
 624   } else {
 625     LeakCldWriter lcldw(_leakp_writer, _class_unload);
 626     CompositeCldWriter ccldw(&lcldw, &cldw);
 627     KlassCompositeCldWriter kccldw(&ccldw);
 628     ModuleCompositeCldWriter mccldw(&ccldw);
 629     KlassAndModuleCompositeCldWriter kmccldw(&kccldw, &mccldw);
 630     _artifacts->iterate_klasses(kmccldw);
 631     ClearArtifact<CldPtr> clear;
 632     CompositeCldWriterWithClear ccldwwc(&ccldw, &clear);
 633     CompositeCldCallback callback(&ccldwwc);
 634     _subsystem_callback = &callback;
 635     do_class_loaders();
 636   }
 637   _artifacts->tally(cldw);
 638 }
 639 
 640 static u1 get_visibility(MethodPtr method) {
 641   assert(method != NULL, "invariant");
 642   return const_cast<Method*>(method)->is_hidden() ? (u1)1 : (u1)0;
 643 }
 644 
 645 template <>
 646 void set_serialized<Method>(MethodPtr method) {
 647   assert(method != NULL, "invariant");
 648   SET_METHOD_SERIALIZED(method);
 649   assert(IS_METHOD_SERIALIZED(method), "invariant");
 650 }
 651 
 652 static int write_method(JfrCheckpointWriter* writer, MethodPtr method, bool leakp) {
 653   assert(writer != NULL, "invariant");
 654   assert(method != NULL, "invariant");
 655   assert(_artifacts != NULL, "invariant");
 656   KlassPtr klass = method->method_holder();
 657   assert(klass != NULL, "invariant");
 658   writer->write(method_id(klass, method));
 659   writer->write(artifact_id(klass));
 660   writer->write(mark_symbol(method->name(), leakp));
 661   writer->write(mark_symbol(method->signature(), leakp));
 662   writer->write((u2)get_flags(method));
 663   writer->write(get_visibility(method));
 664   return 1;
 665 }
 666 
 667 int write__method(JfrCheckpointWriter* writer, const void* m) {
 668   assert(m != NULL, "invariant");
 669   MethodPtr method = (MethodPtr)m;
 670   set_serialized(method);
 671   return write_method(writer, method, false);
 672 }
 673 
 674 int write__method__leakp(JfrCheckpointWriter* writer, const void* m) {
 675   assert(m != NULL, "invariant");
 676   MethodPtr method = (MethodPtr)m;
 677   return write_method(writer, method, true);
 678 }
 679 
 680 class BitMapFilter {
 681   ResourceBitMap _bitmap;
 682  public:
 683   explicit BitMapFilter(int length = 0) : _bitmap((size_t)length) {}
 684   bool operator()(size_t idx) {
 685     if (_bitmap.size() == 0) {
 686       return true;
 687     }
 688     if (_bitmap.at(idx)) {
 689       return false;
 690     }
 691     _bitmap.set_bit(idx);
 692     return true;
 693   }
 694 };
 695 
 696 class AlwaysTrue {
 697  public:
 698   explicit AlwaysTrue(int length = 0) {}
 699   bool operator()(size_t idx) {
 700     return true;
 701   }
 702 };
 703 
 704 template <typename MethodCallback, typename KlassCallback, class Filter, bool leakp>
 705 class MethodIteratorHost {
 706  private:
 707   MethodCallback _method_cb;
 708   KlassCallback _klass_cb;
 709   MethodUsedPredicate<leakp> _method_used_predicate;
 710   MethodFlagPredicate<leakp> _method_flag_predicate;
 711  public:
 712   MethodIteratorHost(JfrCheckpointWriter* writer,
 713                      bool current_epoch = false,
 714                      bool class_unload = false,
 715                      bool skip_header = false) :
 716     _method_cb(writer, class_unload, skip_header),
 717     _klass_cb(writer, class_unload, skip_header),
 718     _method_used_predicate(current_epoch),
 719     _method_flag_predicate(current_epoch) {}
 720 
 721   bool operator()(KlassPtr klass) {
 722     if (_method_used_predicate(klass)) {
 723       const InstanceKlass* ik = InstanceKlass::cast(klass);
 724       const int len = ik->methods()->length();
 725       Filter filter(ik->previous_versions() != NULL ? len : 0);
 726       while (ik != NULL) {
 727         for (int i = 0; i < len; ++i) {
 728           MethodPtr method = ik->methods()->at(i);
 729           if (_method_flag_predicate(method) && filter(i)) {
 730             _method_cb(method);
 731           }
 732         }
 733         // There can be multiple versions of the same method running
 734         // due to redefinition. Need to inspect the complete set of methods.
 735         ik = ik->previous_versions();
 736       }
 737     }
 738     return _klass_cb(klass);
 739   }
 740 
 741   int count() const { return _method_cb.count(); }
 742   void add(int count) { _method_cb.add(count); }
 743 };
 744 
 745 template <typename T, template <typename> class Impl>
 746 class Wrapper {
 747   Impl<T> _t;
 748  public:
 749   Wrapper(JfrCheckpointWriter*, bool, bool) : _t() {}
 750   bool operator()(T const& value) {
 751     return _t(value);
 752   }
 753 };
 754 
 755 template <typename T>
 756 class EmptyStub {
 757  public:
 758   bool operator()(T const& value) { return true; }
 759 };
 760 
 761 typedef SerializePredicate<MethodPtr> MethodPredicate;
 762 typedef JfrPredicatedTypeWriterImplHost<MethodPtr, MethodPredicate, write__method> MethodWriterImplTarget;
 763 typedef Wrapper<KlassPtr, EmptyStub> KlassCallbackStub;
 764 typedef JfrTypeWriterHost<MethodWriterImplTarget, TYPE_METHOD> MethodWriterImpl;
 765 typedef MethodIteratorHost<MethodWriterImpl, KlassCallbackStub, BitMapFilter, false> MethodWriter;
 766 
 767 typedef LeakPredicate<MethodPtr> LeakMethodPredicate;
 768 typedef JfrPredicatedTypeWriterImplHost<MethodPtr, LeakMethodPredicate, write__method__leakp> LeakMethodWriterImplTarget;
 769 typedef JfrTypeWriterHost<LeakMethodWriterImplTarget, TYPE_METHOD> LeakMethodWriterImpl;
 770 typedef MethodIteratorHost<LeakMethodWriterImpl, KlassCallbackStub, BitMapFilter, true> LeakMethodWriter;
 771 typedef MethodIteratorHost<LeakMethodWriterImpl, KlassCallbackStub, BitMapFilter, true> LeakMethodWriter;
 772 typedef CompositeFunctor<KlassPtr, LeakMethodWriter, MethodWriter> CompositeMethodWriter;
 773 
 774 static void write_methods() {
 775   assert(_writer != NULL, "invariant");
 776   MethodWriter mw(_writer, current_epoch(), _class_unload);
 777   if (_leakp_writer == NULL) {
 778     _artifacts->iterate_klasses(mw);
 779   } else {
 780     LeakMethodWriter lpmw(_leakp_writer, current_epoch(), _class_unload);
 781     CompositeMethodWriter cmw(&lpmw, &mw);
 782     _artifacts->iterate_klasses(cmw);
 783   }
 784   _artifacts->tally(mw);
 785 }
 786 
 787 template <>
 788 void set_serialized<JfrSymbolId::SymbolEntry>(SymbolEntryPtr ptr) {
 789   assert(ptr != NULL, "invariant");
 790   ptr->set_serialized();
 791   assert(ptr->is_serialized(), "invariant");
 792 }
 793 
 794 template <>
 795 void set_serialized<JfrSymbolId::CStringEntry>(CStringEntryPtr ptr) {
 796   assert(ptr != NULL, "invariant");
 797   ptr->set_serialized();
 798   assert(ptr->is_serialized(), "invariant");
 799 }
 800 
 801 static int write_symbol(JfrCheckpointWriter* writer, SymbolEntryPtr entry, bool leakp) {
 802   assert(writer != NULL, "invariant");
 803   assert(entry != NULL, "invariant");
 804   ResourceMark rm;
 805   writer->write(create_symbol_id(entry->id()));
 806   writer->write(entry->value()->as_C_string());
 807   return 1;
 808 }
 809 
 810 int write__symbol(JfrCheckpointWriter* writer, const void* e) {
 811   assert(e != NULL, "invariant");
 812   SymbolEntryPtr entry = (SymbolEntryPtr)e;
 813   set_serialized(entry);
 814   return write_symbol(writer, entry, false);
 815 }
 816 
 817 int write__symbol__leakp(JfrCheckpointWriter* writer, const void* e) {
 818   assert(e != NULL, "invariant");
 819   SymbolEntryPtr entry = (SymbolEntryPtr)e;
 820   return write_symbol(writer, entry, true);
 821 }
 822 
 823 static int write_cstring(JfrCheckpointWriter* writer, CStringEntryPtr entry, bool leakp) {
 824   assert(writer != NULL, "invariant");
 825   assert(entry != NULL, "invariant");
 826   writer->write(create_symbol_id(entry->id()));
 827   writer->write(entry->value());
 828   return 1;
 829 }
 830 
 831 int write__cstring(JfrCheckpointWriter* writer, const void* e) {
 832   assert(e != NULL, "invariant");
 833   CStringEntryPtr entry = (CStringEntryPtr)e;
 834   set_serialized(entry);
 835   return write_cstring(writer, entry, false);
 836 }
 837 
 838 int write__cstring__leakp(JfrCheckpointWriter* writer, const void* e) {
 839   assert(e != NULL, "invariant");
 840   CStringEntryPtr entry = (CStringEntryPtr)e;
 841   return write_cstring(writer, entry, true);
 842 }
 843 
 844 typedef SymbolPredicate<SymbolEntryPtr, false> SymPredicate;
 845 typedef JfrPredicatedTypeWriterImplHost<SymbolEntryPtr, SymPredicate, write__symbol> SymbolEntryWriterImpl;
 846 typedef JfrTypeWriterHost<SymbolEntryWriterImpl, TYPE_SYMBOL> SymbolEntryWriter;
 847 typedef SymbolPredicate<CStringEntryPtr, false> CStringPredicate;
 848 typedef JfrPredicatedTypeWriterImplHost<CStringEntryPtr, CStringPredicate, write__cstring> CStringEntryWriterImpl;
 849 typedef JfrTypeWriterHost<CStringEntryWriterImpl, TYPE_SYMBOL> CStringEntryWriter;
 850 
 851 typedef SymbolPredicate<SymbolEntryPtr, true> LeakSymPredicate;
 852 typedef JfrPredicatedTypeWriterImplHost<SymbolEntryPtr, LeakSymPredicate, write__symbol__leakp> LeakSymbolEntryWriterImpl;
 853 typedef JfrTypeWriterHost<LeakSymbolEntryWriterImpl, TYPE_SYMBOL> LeakSymbolEntryWriter;
 854 typedef CompositeFunctor<SymbolEntryPtr, LeakSymbolEntryWriter, SymbolEntryWriter> CompositeSymbolWriter;
 855 typedef SymbolPredicate<CStringEntryPtr, true> LeakCStringPredicate;
 856 typedef JfrPredicatedTypeWriterImplHost<CStringEntryPtr, LeakCStringPredicate, write__cstring__leakp> LeakCStringEntryWriterImpl;
 857 typedef JfrTypeWriterHost<LeakCStringEntryWriterImpl, TYPE_SYMBOL> LeakCStringEntryWriter;
 858 typedef CompositeFunctor<CStringEntryPtr, LeakCStringEntryWriter, CStringEntryWriter> CompositeCStringWriter;
 859 
 860 static void write_symbols_with_leakp() {
 861   assert(_leakp_writer != NULL, "invariant");
 862   SymbolEntryWriter sw(_writer, _class_unload);
 863   LeakSymbolEntryWriter lsw(_leakp_writer, _class_unload);
 864   CompositeSymbolWriter csw(&lsw, &sw);
 865   _artifacts->iterate_symbols(csw);
 866   CStringEntryWriter ccsw(_writer, _class_unload, true); // skip header
 867   LeakCStringEntryWriter lccsw(_leakp_writer, _class_unload, true); // skip header
 868   CompositeCStringWriter cccsw(&lccsw, &ccsw);
 869   _artifacts->iterate_cstrings(cccsw);
 870   sw.add(ccsw.count());
 871   lsw.add(lccsw.count());
 872   _artifacts->tally(sw);
 873 }
 874 
 875 static void write_symbols() {
 876   assert(_writer != NULL, "invariant");
 877   if (_leakp_writer != NULL) {
 878     write_symbols_with_leakp();
 879     return;
 880   }
 881   SymbolEntryWriter sw(_writer, _class_unload);
 882   _artifacts->iterate_symbols(sw);
 883   CStringEntryWriter csw(_writer, _class_unload, true); // skip header
 884   _artifacts->iterate_cstrings(csw);
 885   sw.add(csw.count());
 886   _artifacts->tally(sw);
 887 }
 888 
 889 static bool clear_artifacts = false;
 890 
 891 void JfrTypeSet::clear() {
 892   clear_artifacts = true;
 893 }
 894 
 895 typedef Wrapper<KlassPtr, ClearArtifact> ClearKlassBits;
 896 typedef Wrapper<MethodPtr, ClearArtifact> ClearMethodFlag;
 897 typedef MethodIteratorHost<ClearMethodFlag, ClearKlassBits, AlwaysTrue, false> ClearKlassAndMethods;
 898 
 899 static size_t teardown() {
 900   assert(_artifacts != NULL, "invariant");
 901   const size_t total_count = _artifacts->total_count();
 902   if (previous_epoch()) {
 903     assert(_writer != NULL, "invariant");
 904     ClearKlassAndMethods clear(_writer);
 905     _artifacts->iterate_klasses(clear);
 906     JfrTypeSet::clear();
 907     ++checkpoint_id;
 908   }
 909   return total_count;
 910 }
 911 
 912 static void setup(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer, bool class_unload, bool flushpoint) {
 913   _writer = writer;
 914   _leakp_writer = leakp_writer;
 915   _class_unload = class_unload;
 916   _flushpoint = flushpoint;
 917   if (_artifacts == NULL) {
 918     _artifacts = new JfrArtifactSet(class_unload);
 919   } else {
 920     _artifacts->initialize(class_unload, clear_artifacts);
 921   }
 922   clear_artifacts = false;
 923   assert(_artifacts != NULL, "invariant");
 924   assert(!_artifacts->has_klass_entries(), "invariant");
 925 }
 926 
 927 /**
 928  * Write all "tagged" (in-use) constant artifacts and their dependencies.
 929  */
 930 size_t JfrTypeSet::serialize(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer, bool class_unload, bool flushpoint) {
 931   assert(writer != NULL, "invariant");
 932   ResourceMark rm;
 933   setup(writer, leakp_writer, class_unload, flushpoint);
 934   // write order is important because an individual write step
 935   // might tag an artifact to be written in a subsequent step
 936   if (!write_klasses()) {
 937     return 0;
 938   }
 939   write_packages();
 940   write_modules();
 941   write_classloaders();
 942   write_methods();
 943   write_symbols();
 944   return teardown();
 945 }