1 /*
   2  * Copyright (c) 2016, 2020, 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   assert(!cld->is_unsafe_anonymous(), "invariant");
 141   if (leakp) {
 142     SET_LEAKP(cld);
 143   } else {
 144     SET_TRANSIENT(cld);
 145   }
 146   return artifact_id(cld);
 147 }
 148 
 149 template <typename T>
 150 static s4 get_flags(const T* ptr) {
 151   assert(ptr != NULL, "invariant");
 152   return ptr->access_flags().get_flags();
 153 }
 154 
 155 static bool is_unsafe_anonymous(const Klass* klass) {
 156   assert(klass != NULL, "invariant");
 157   assert(!klass->is_objArray_klass(), "invariant");
 158   return klass->is_instance_klass() && InstanceKlass::cast(klass)->is_unsafe_anonymous();
 159 }
 160 
 161 static ClassLoaderData* get_cld(const Klass* klass) {
 162   assert(klass != NULL, "invariant");
 163   if (klass->is_objArray_klass()) {
 164     klass = ObjArrayKlass::cast(klass)->bottom_klass();
 165   }
 166   return is_unsafe_anonymous(klass) ?
 167     InstanceKlass::cast(klass)->unsafe_anonymous_host()->class_loader_data() : klass->class_loader_data();
 168 }
 169 
 170 template <typename T>
 171 static void set_serialized(const T* ptr) {
 172   assert(ptr != NULL, "invariant");
 173   SET_SERIALIZED(ptr);
 174   assert(IS_SERIALIZED(ptr), "invariant");
 175   CLEAR_THIS_EPOCH_CLEARED_BIT(ptr);
 176 }
 177 
 178 /*
 179  * In C++03, functions used as template parameters must have external linkage;
 180  * this restriction was removed in C++11. Change back to "static" and
 181  * rename functions when C++11 becomes available.
 182  *
 183  * The weird naming is an effort to decrease the risk of name clashes.
 184  */
 185 
 186 static int write_klass(JfrCheckpointWriter* writer, KlassPtr klass, bool leakp) {
 187   assert(writer != NULL, "invariant");
 188   assert(_artifacts != NULL, "invariant");
 189   assert(klass != NULL, "invariant");
 190   writer->write(artifact_id(klass));
 191   writer->write(cld_id(get_cld(klass), leakp));
 192   writer->write(mark_symbol(klass, leakp));
 193   writer->write(package_id(klass, leakp));
 194   writer->write(get_flags(klass));
 195   return 1;
 196 }
 197 
 198 int write__klass(JfrCheckpointWriter* writer, const void* k) {
 199   assert(k != NULL, "invariant");
 200   KlassPtr klass = (KlassPtr)k;
 201   set_serialized(klass);
 202   return write_klass(writer, klass, false);
 203 }
 204 
 205 int write__klass__leakp(JfrCheckpointWriter* writer, const void* k) {
 206   assert(k != NULL, "invariant");
 207   KlassPtr klass = (KlassPtr)k;
 208   return write_klass(writer, klass, true);
 209 }
 210 
 211 static bool is_implied(const Klass* klass) {
 212   assert(klass != NULL, "invariant");
 213   return klass->is_subclass_of(SystemDictionary::ClassLoader_klass()) || klass == SystemDictionary::Object_klass();
 214 }
 215 
 216 static void do_implied(Klass* klass) {
 217   assert(klass != NULL, "invariant");
 218   if (is_implied(klass)) {
 219     if (_leakp_writer != NULL) {
 220       SET_LEAKP(klass);
 221     }
 222     _subsystem_callback->do_artifact(klass);
 223   }
 224 }
 225 
 226 static void do_unloaded_klass(Klass* klass) {
 227   assert(klass != NULL, "invariant");
 228   assert(_subsystem_callback != NULL, "invariant");
 229   if (IS_JDK_JFR_EVENT_SUBKLASS(klass)) {
 230     JfrEventClasses::increment_unloaded_event_class();
 231   }
 232   if (USED_THIS_EPOCH(klass)) {
 233     ObjectSampleCheckpoint::on_klass_unload(klass);
 234     _subsystem_callback->do_artifact(klass);
 235     return;
 236   }
 237   do_implied(klass);
 238 }
 239 
 240 static void do_klass(Klass* klass) {
 241   assert(klass != NULL, "invariant");
 242   assert(_subsystem_callback != NULL, "invariant");
 243   if (_flushpoint) {
 244     if (USED_THIS_EPOCH(klass)) {
 245       _subsystem_callback->do_artifact(klass);
 246       return;
 247     }
 248   } else {
 249     if (USED_PREV_EPOCH(klass)) {
 250       _subsystem_callback->do_artifact(klass);
 251       return;
 252     }
 253   }
 254   do_implied(klass);
 255 }
 256 
 257 static void do_klasses() {
 258   if (_class_unload) {
 259     ClassLoaderDataGraph::classes_unloading_do(&do_unloaded_klass);
 260     return;
 261   }
 262   ClassLoaderDataGraph::classes_do(&do_klass);
 263 }
 264 
 265 typedef SerializePredicate<KlassPtr> KlassPredicate;
 266 typedef JfrPredicatedTypeWriterImplHost<KlassPtr, KlassPredicate, write__klass> KlassWriterImpl;
 267 typedef JfrTypeWriterHost<KlassWriterImpl, TYPE_CLASS> KlassWriter;
 268 typedef CompositeFunctor<KlassPtr, KlassWriter, KlassArtifactRegistrator> KlassWriterRegistration;
 269 typedef JfrArtifactCallbackHost<KlassPtr, KlassWriterRegistration> KlassCallback;
 270 
 271 template <>
 272 class LeakPredicate<const Klass*> {
 273 public:
 274   LeakPredicate(bool class_unload) {}
 275   bool operator()(const Klass* klass) {
 276     assert(klass != NULL, "invariant");
 277     return IS_LEAKP(klass) || is_implied(klass);
 278   }
 279 };
 280 
 281 typedef LeakPredicate<KlassPtr> LeakKlassPredicate;
 282 typedef JfrPredicatedTypeWriterImplHost<KlassPtr, LeakKlassPredicate, write__klass__leakp> LeakKlassWriterImpl;
 283 typedef JfrTypeWriterHost<LeakKlassWriterImpl, TYPE_CLASS> LeakKlassWriter;
 284 
 285 typedef CompositeFunctor<KlassPtr, LeakKlassWriter, KlassWriter> CompositeKlassWriter;
 286 typedef CompositeFunctor<KlassPtr, CompositeKlassWriter, KlassArtifactRegistrator> CompositeKlassWriterRegistration;
 287 typedef JfrArtifactCallbackHost<KlassPtr, CompositeKlassWriterRegistration> CompositeKlassCallback;
 288 
 289 static bool write_klasses() {
 290   assert(!_artifacts->has_klass_entries(), "invariant");
 291   assert(_writer != NULL, "invariant");
 292   KlassArtifactRegistrator reg(_artifacts);
 293   KlassWriter kw(_writer, _class_unload);
 294   KlassWriterRegistration kwr(&kw, &reg);
 295   if (_leakp_writer == NULL) {
 296     KlassCallback callback(&kwr);
 297     _subsystem_callback = &callback;
 298     do_klasses();
 299   } else {
 300     LeakKlassWriter lkw(_leakp_writer, _class_unload);
 301     CompositeKlassWriter ckw(&lkw, &kw);
 302     CompositeKlassWriterRegistration ckwr(&ckw, &reg);
 303     CompositeKlassCallback callback(&ckwr);
 304     _subsystem_callback = &callback;
 305     do_klasses();
 306   }
 307   if (is_complete()) {
 308     return false;
 309   }
 310   _artifacts->tally(kw);
 311   return true;
 312 }
 313 
 314 template <typename T>
 315 static void do_previous_epoch_artifact(JfrArtifactClosure* callback, T* value) {
 316   assert(callback != NULL, "invariant");
 317   assert(value != NULL, "invariant");
 318   if (USED_PREV_EPOCH(value)) {
 319     callback->do_artifact(value);
 320     assert(IS_NOT_SERIALIZED(value), "invariant");
 321     return;
 322   }
 323   if (IS_SERIALIZED(value)) {
 324     CLEAR_SERIALIZED(value);
 325   }
 326   assert(IS_NOT_SERIALIZED(value), "invariant");
 327 }
 328 
 329 typedef JfrArtifactCallbackHost<KlassPtr, KlassArtifactRegistrator> RegistrationCallback;
 330 
 331 static void register_klass(Klass* klass) {
 332   assert(klass != NULL, "invariant");
 333   assert(_subsystem_callback != NULL, "invariant");
 334   do_previous_epoch_artifact(_subsystem_callback, klass);
 335 }
 336 
 337 static void do_register_klasses() {
 338   ClassLoaderDataGraph::classes_do(&register_klass);
 339 }
 340 
 341 static void register_klasses() {
 342   assert(!_artifacts->has_klass_entries(), "invariant");
 343   KlassArtifactRegistrator reg(_artifacts);
 344   RegistrationCallback callback(&reg);
 345   _subsystem_callback = &callback;
 346   do_register_klasses();
 347 }
 348 
 349 static int write_package(JfrCheckpointWriter* writer, PkgPtr pkg, bool leakp) {
 350   assert(writer != NULL, "invariant");
 351   assert(_artifacts != NULL, "invariant");
 352   assert(pkg != NULL, "invariant");
 353   writer->write(artifact_id(pkg));
 354   writer->write(mark_symbol(pkg->name(), leakp));
 355   writer->write(module_id(pkg, leakp));
 356   writer->write((bool)pkg->is_exported());
 357   return 1;
 358 }
 359 
 360 int write__package(JfrCheckpointWriter* writer, const void* p) {
 361   assert(p != NULL, "invariant");
 362   PkgPtr pkg = (PkgPtr)p;
 363   set_serialized(pkg);
 364   return write_package(writer, pkg, false);
 365 }
 366 
 367 int write__package__leakp(JfrCheckpointWriter* writer, const void* p) {
 368   assert(p != NULL, "invariant");
 369   PkgPtr pkg = (PkgPtr)p;
 370   CLEAR_LEAKP(pkg);
 371   return write_package(writer, pkg, true);
 372 }
 373 
 374 static void do_package(PackageEntry* entry) {
 375   do_previous_epoch_artifact(_subsystem_callback, entry);
 376 }
 377 
 378 static void do_packages() {
 379   ClassLoaderDataGraph::packages_do(&do_package);
 380 }
 381 
 382 class PackageFieldSelector {
 383  public:
 384   typedef PkgPtr TypePtr;
 385   static TypePtr select(KlassPtr klass) {
 386     assert(klass != NULL, "invariant");
 387     return klass->package();
 388   }
 389 };
 390 
 391 typedef SerializePredicate<PkgPtr> PackagePredicate;
 392 typedef JfrPredicatedTypeWriterImplHost<PkgPtr, PackagePredicate, write__package> PackageWriterImpl;
 393 typedef JfrTypeWriterHost<PackageWriterImpl, TYPE_PACKAGE> PackageWriter;
 394 typedef CompositeFunctor<PkgPtr, PackageWriter, ClearArtifact<PkgPtr> > PackageWriterWithClear;
 395 typedef KlassToFieldEnvelope<PackageFieldSelector, PackageWriter> KlassPackageWriter;
 396 typedef JfrArtifactCallbackHost<PkgPtr, PackageWriterWithClear> PackageCallback;
 397 
 398 typedef LeakPredicate<PkgPtr> LeakPackagePredicate;
 399 typedef JfrPredicatedTypeWriterImplHost<PkgPtr, LeakPackagePredicate, write__package__leakp> LeakPackageWriterImpl;
 400 typedef JfrTypeWriterHost<LeakPackageWriterImpl, TYPE_PACKAGE> LeakPackageWriter;
 401 
 402 typedef CompositeFunctor<PkgPtr, LeakPackageWriter, PackageWriter> CompositePackageWriter;
 403 typedef KlassToFieldEnvelope<PackageFieldSelector, CompositePackageWriter> KlassCompositePackageWriter;
 404 typedef KlassToFieldEnvelope<PackageFieldSelector, PackageWriterWithClear> KlassPackageWriterWithClear;
 405 typedef CompositeFunctor<PkgPtr, CompositePackageWriter, ClearArtifact<PkgPtr> > CompositePackageWriterWithClear;
 406 typedef JfrArtifactCallbackHost<PkgPtr, CompositePackageWriterWithClear> CompositePackageCallback;
 407 
 408 static void write_packages() {
 409   assert(_writer != NULL, "invariant");
 410   PackageWriter pw(_writer, _class_unload);
 411   KlassPackageWriter kpw(&pw);
 412   if (current_epoch()) {
 413     _artifacts->iterate_klasses(kpw);
 414     _artifacts->tally(pw);
 415     return;
 416   }
 417   assert(previous_epoch(), "invariant");
 418   if (_leakp_writer == NULL) {
 419     _artifacts->iterate_klasses(kpw);
 420     ClearArtifact<PkgPtr> clear;
 421     PackageWriterWithClear pwwc(&pw, &clear);
 422     PackageCallback callback(&pwwc);
 423     _subsystem_callback = &callback;
 424     do_packages();
 425   } else {
 426     LeakPackageWriter lpw(_leakp_writer, _class_unload);
 427     CompositePackageWriter cpw(&lpw, &pw);
 428     KlassCompositePackageWriter kcpw(&cpw);
 429     _artifacts->iterate_klasses(kcpw);
 430     ClearArtifact<PkgPtr> clear;
 431     CompositePackageWriterWithClear cpwwc(&cpw, &clear);
 432     CompositePackageCallback callback(&cpwwc);
 433     _subsystem_callback = &callback;
 434     do_packages();
 435   }
 436   _artifacts->tally(pw);
 437 }
 438 
 439 typedef JfrArtifactCallbackHost<PkgPtr, ClearArtifact<PkgPtr> > ClearPackageCallback;
 440 
 441 static void clear_packages() {
 442   ClearArtifact<PkgPtr> clear;
 443   ClearPackageCallback callback(&clear);
 444   _subsystem_callback = &callback;
 445   do_packages();
 446 }
 447 
 448 static int write_module(JfrCheckpointWriter* writer, ModPtr mod, bool leakp) {
 449   assert(mod != NULL, "invariant");
 450   assert(_artifacts != NULL, "invariant");
 451   writer->write(artifact_id(mod));
 452   writer->write(mark_symbol(mod->name(), leakp));
 453   writer->write(mark_symbol(mod->version(), leakp));
 454   writer->write(mark_symbol(mod->location(), leakp));
 455   writer->write(cld_id(mod->loader_data(), leakp));
 456   return 1;
 457 }
 458 
 459 int write__module(JfrCheckpointWriter* writer, const void* m) {
 460   assert(m != NULL, "invariant");
 461   ModPtr mod = (ModPtr)m;
 462   set_serialized(mod);
 463   return write_module(writer, mod, false);
 464 }
 465 
 466 int write__module__leakp(JfrCheckpointWriter* writer, const void* m) {
 467   assert(m != NULL, "invariant");
 468   ModPtr mod = (ModPtr)m;
 469   CLEAR_LEAKP(mod);
 470   return write_module(writer, mod, true);
 471 }
 472 
 473 static void do_module(ModuleEntry* entry) {
 474   do_previous_epoch_artifact(_subsystem_callback, entry);
 475 }
 476 
 477 static void do_modules() {
 478   ClassLoaderDataGraph::modules_do(&do_module);
 479 }
 480 
 481 class ModuleFieldSelector {
 482  public:
 483   typedef ModPtr TypePtr;
 484   static TypePtr select(KlassPtr klass) {
 485     assert(klass != NULL, "invariant");
 486     PkgPtr pkg = klass->package();
 487     return pkg != NULL ? pkg->module() : NULL;
 488   }
 489 };
 490 
 491 typedef SerializePredicate<ModPtr> ModulePredicate;
 492 typedef JfrPredicatedTypeWriterImplHost<ModPtr, ModulePredicate, write__module> ModuleWriterImpl;
 493 typedef JfrTypeWriterHost<ModuleWriterImpl, TYPE_MODULE> ModuleWriter;
 494 typedef CompositeFunctor<ModPtr, ModuleWriter, ClearArtifact<ModPtr> > ModuleWriterWithClear;
 495 typedef JfrArtifactCallbackHost<ModPtr, ModuleWriterWithClear> ModuleCallback;
 496 typedef KlassToFieldEnvelope<ModuleFieldSelector, ModuleWriter> KlassModuleWriter;
 497 
 498 typedef LeakPredicate<ModPtr> LeakModulePredicate;
 499 typedef JfrPredicatedTypeWriterImplHost<ModPtr, LeakModulePredicate, write__module__leakp> LeakModuleWriterImpl;
 500 typedef JfrTypeWriterHost<LeakModuleWriterImpl, TYPE_MODULE> LeakModuleWriter;
 501 
 502 typedef CompositeFunctor<ModPtr, LeakModuleWriter, ModuleWriter> CompositeModuleWriter;
 503 typedef KlassToFieldEnvelope<ModuleFieldSelector, CompositeModuleWriter> KlassCompositeModuleWriter;
 504 typedef CompositeFunctor<ModPtr, CompositeModuleWriter, ClearArtifact<ModPtr> > CompositeModuleWriterWithClear;
 505 typedef JfrArtifactCallbackHost<ModPtr, CompositeModuleWriterWithClear> CompositeModuleCallback;
 506 
 507 static void write_modules() {
 508   assert(_writer != NULL, "invariant");
 509   ModuleWriter mw(_writer, _class_unload);
 510   KlassModuleWriter kmw(&mw);
 511   if (current_epoch()) {
 512     _artifacts->iterate_klasses(kmw);
 513     _artifacts->tally(mw);
 514     return;
 515   }
 516   assert(previous_epoch(), "invariant");
 517   if (_leakp_writer == NULL) {
 518     _artifacts->iterate_klasses(kmw);
 519     ClearArtifact<ModPtr> clear;
 520     ModuleWriterWithClear mwwc(&mw, &clear);
 521     ModuleCallback callback(&mwwc);
 522     _subsystem_callback = &callback;
 523     do_modules();
 524   } else {
 525     LeakModuleWriter lmw(_leakp_writer, _class_unload);
 526     CompositeModuleWriter cmw(&lmw, &mw);
 527     KlassCompositeModuleWriter kcpw(&cmw);
 528     _artifacts->iterate_klasses(kcpw);
 529     ClearArtifact<ModPtr> clear;
 530     CompositeModuleWriterWithClear cmwwc(&cmw, &clear);
 531     CompositeModuleCallback callback(&cmwwc);
 532     _subsystem_callback = &callback;
 533     do_modules();
 534   }
 535   _artifacts->tally(mw);
 536 }
 537 
 538 typedef JfrArtifactCallbackHost<ModPtr, ClearArtifact<ModPtr> > ClearModuleCallback;
 539 
 540 static void clear_modules() {
 541   ClearArtifact<ModPtr> clear;
 542   ClearModuleCallback callback(&clear);
 543   _subsystem_callback = &callback;
 544   do_modules();
 545 }
 546 
 547 static int write_classloader(JfrCheckpointWriter* writer, CldPtr cld, bool leakp) {
 548   assert(cld != NULL, "invariant");
 549   assert(!cld->is_unsafe_anonymous(), "invariant");
 550   // class loader type
 551   const Klass* class_loader_klass = cld->class_loader_klass();
 552   if (class_loader_klass == NULL) {
 553     // (primordial) boot class loader
 554     writer->write(artifact_id(cld)); // class loader instance id
 555     writer->write((traceid)0);  // class loader type id (absence of)
 556     writer->write(get_bootstrap_name(leakp)); // maps to synthetic name -> "bootstrap"
 557   } else {
 558     writer->write(artifact_id(cld)); // class loader instance id
 559     writer->write(artifact_id(class_loader_klass)); // class loader type id
 560     writer->write(mark_symbol(cld->name(), leakp)); // class loader instance name
 561   }
 562   return 1;
 563 }
 564 
 565 int write__classloader(JfrCheckpointWriter* writer, const void* c) {
 566   assert(c != NULL, "invariant");
 567   CldPtr cld = (CldPtr)c;
 568   set_serialized(cld);
 569   return write_classloader(writer, cld, false);
 570 }
 571 
 572 int write__classloader__leakp(JfrCheckpointWriter* writer, const void* c) {
 573   assert(c != NULL, "invariant");
 574   CldPtr cld = (CldPtr)c;
 575   CLEAR_LEAKP(cld);
 576   return write_classloader(writer, cld, true);
 577 }
 578 
 579 static void do_class_loader_data(ClassLoaderData* cld) {
 580   do_previous_epoch_artifact(_subsystem_callback, cld);
 581 }
 582 
 583 class KlassCldFieldSelector {
 584  public:
 585   typedef CldPtr TypePtr;
 586   static TypePtr select(KlassPtr klass) {
 587     assert(klass != NULL, "invariant");
 588     return get_cld(klass);
 589   }
 590 };
 591 
 592 class ModuleCldFieldSelector {
 593 public:
 594   typedef CldPtr TypePtr;
 595   static TypePtr select(KlassPtr klass) {
 596     assert(klass != NULL, "invariant");
 597     ModPtr mod = ModuleFieldSelector::select(klass);
 598     return mod != NULL ? mod->loader_data() : NULL;
 599   }
 600 };
 601 
 602 class CLDCallback : public CLDClosure {
 603  public:
 604   CLDCallback() {}
 605   void do_cld(ClassLoaderData* cld) {
 606     assert(cld != NULL, "invariant");
 607     if (cld->is_unsafe_anonymous()) {
 608       return;
 609     }
 610     do_class_loader_data(cld);
 611   }
 612 };
 613 
 614 static void do_class_loaders() {
 615   CLDCallback cld_cb;
 616   ClassLoaderDataGraph::loaded_cld_do(&cld_cb);
 617 }
 618 
 619 typedef SerializePredicate<CldPtr> CldPredicate;
 620 typedef JfrPredicatedTypeWriterImplHost<CldPtr, CldPredicate, write__classloader> CldWriterImpl;
 621 typedef JfrTypeWriterHost<CldWriterImpl, TYPE_CLASSLOADER> CldWriter;
 622 typedef CompositeFunctor<CldPtr, CldWriter, ClearArtifact<CldPtr> > CldWriterWithClear;
 623 typedef JfrArtifactCallbackHost<CldPtr, CldWriterWithClear> CldCallback;
 624 typedef KlassToFieldEnvelope<KlassCldFieldSelector, CldWriter> KlassCldWriter;
 625 typedef KlassToFieldEnvelope<ModuleCldFieldSelector, CldWriter> ModuleCldWriter;
 626 typedef CompositeFunctor<KlassPtr, KlassCldWriter, ModuleCldWriter> KlassAndModuleCldWriter;
 627 
 628 typedef LeakPredicate<CldPtr> LeakCldPredicate;
 629 typedef JfrPredicatedTypeWriterImplHost<CldPtr, LeakCldPredicate, write__classloader__leakp> LeakCldWriterImpl;
 630 typedef JfrTypeWriterHost<LeakCldWriterImpl, TYPE_CLASSLOADER> LeakCldWriter;
 631 
 632 typedef CompositeFunctor<CldPtr, LeakCldWriter, CldWriter> CompositeCldWriter;
 633 typedef KlassToFieldEnvelope<KlassCldFieldSelector, CompositeCldWriter> KlassCompositeCldWriter;
 634 typedef KlassToFieldEnvelope<ModuleCldFieldSelector, CompositeCldWriter> ModuleCompositeCldWriter;
 635 typedef CompositeFunctor<KlassPtr, KlassCompositeCldWriter, ModuleCompositeCldWriter> KlassAndModuleCompositeCldWriter;
 636 typedef CompositeFunctor<CldPtr, CompositeCldWriter, ClearArtifact<CldPtr> > CompositeCldWriterWithClear;
 637 typedef JfrArtifactCallbackHost<CldPtr, CompositeCldWriterWithClear> CompositeCldCallback;
 638 
 639 static void write_classloaders() {
 640   assert(_writer != NULL, "invariant");
 641   CldWriter cldw(_writer, _class_unload);
 642   KlassCldWriter kcw(&cldw);
 643   ModuleCldWriter mcw(&cldw);
 644   KlassAndModuleCldWriter kmcw(&kcw, &mcw);
 645   if (current_epoch()) {
 646     _artifacts->iterate_klasses(kmcw);
 647     _artifacts->tally(cldw);
 648     return;
 649   }
 650   assert(previous_epoch(), "invariant");
 651   if (_leakp_writer == NULL) {
 652     _artifacts->iterate_klasses(kmcw);
 653     ClearArtifact<CldPtr> clear;
 654     CldWriterWithClear cldwwc(&cldw, &clear);
 655     CldCallback callback(&cldwwc);
 656     _subsystem_callback = &callback;
 657     do_class_loaders();
 658   } else {
 659     LeakCldWriter lcldw(_leakp_writer, _class_unload);
 660     CompositeCldWriter ccldw(&lcldw, &cldw);
 661     KlassCompositeCldWriter kccldw(&ccldw);
 662     ModuleCompositeCldWriter mccldw(&ccldw);
 663     KlassAndModuleCompositeCldWriter kmccldw(&kccldw, &mccldw);
 664     _artifacts->iterate_klasses(kmccldw);
 665     ClearArtifact<CldPtr> clear;
 666     CompositeCldWriterWithClear ccldwwc(&ccldw, &clear);
 667     CompositeCldCallback callback(&ccldwwc);
 668     _subsystem_callback = &callback;
 669     do_class_loaders();
 670   }
 671   _artifacts->tally(cldw);
 672 }
 673 
 674 typedef JfrArtifactCallbackHost<CldPtr, ClearArtifact<CldPtr> > ClearCLDCallback;
 675 
 676 static void clear_classloaders() {
 677   ClearArtifact<CldPtr> clear;
 678   ClearCLDCallback callback(&clear);
 679   _subsystem_callback = &callback;
 680   do_class_loaders();
 681 }
 682 
 683 static u1 get_visibility(MethodPtr method) {
 684   assert(method != NULL, "invariant");
 685   return const_cast<Method*>(method)->is_hidden() ? (u1)1 : (u1)0;
 686 }
 687 
 688 template <>
 689 void set_serialized<Method>(MethodPtr method) {
 690   assert(method != NULL, "invariant");
 691   SET_METHOD_SERIALIZED(method);
 692   assert(IS_METHOD_SERIALIZED(method), "invariant");
 693   CLEAR_THIS_EPOCH_METHOD_CLEARED_BIT(method);
 694 }
 695 
 696 static int write_method(JfrCheckpointWriter* writer, MethodPtr method, bool leakp) {
 697   assert(writer != NULL, "invariant");
 698   assert(method != NULL, "invariant");
 699   assert(_artifacts != NULL, "invariant");
 700   KlassPtr klass = method->method_holder();
 701   assert(klass != NULL, "invariant");
 702   writer->write(method_id(klass, method));
 703   writer->write(artifact_id(klass));
 704   writer->write(mark_symbol(method->name(), leakp));
 705   writer->write(mark_symbol(method->signature(), leakp));
 706   writer->write((u2)get_flags(method));
 707   writer->write(get_visibility(method));
 708   return 1;
 709 }
 710 
 711 int write__method(JfrCheckpointWriter* writer, const void* m) {
 712   assert(m != NULL, "invariant");
 713   MethodPtr method = (MethodPtr)m;
 714   set_serialized(method);
 715   return write_method(writer, method, false);
 716 }
 717 
 718 int write__method__leakp(JfrCheckpointWriter* writer, const void* m) {
 719   assert(m != NULL, "invariant");
 720   MethodPtr method = (MethodPtr)m;
 721   return write_method(writer, method, true);
 722 }
 723 
 724 class BitMapFilter {
 725   ResourceBitMap _bitmap;
 726  public:
 727   explicit BitMapFilter(int length = 0) : _bitmap((size_t)length) {}
 728   bool operator()(size_t idx) {
 729     if (_bitmap.size() == 0) {
 730       return true;
 731     }
 732     if (_bitmap.at(idx)) {
 733       return false;
 734     }
 735     _bitmap.set_bit(idx);
 736     return true;
 737   }
 738 };
 739 
 740 class AlwaysTrue {
 741  public:
 742   explicit AlwaysTrue(int length = 0) {}
 743   bool operator()(size_t idx) {
 744     return true;
 745   }
 746 };
 747 
 748 template <typename MethodCallback, typename KlassCallback, class Filter, bool leakp>
 749 class MethodIteratorHost {
 750  private:
 751   MethodCallback _method_cb;
 752   KlassCallback _klass_cb;
 753   MethodUsedPredicate<leakp> _method_used_predicate;
 754   MethodFlagPredicate<leakp> _method_flag_predicate;
 755  public:
 756   MethodIteratorHost(JfrCheckpointWriter* writer,
 757                      bool current_epoch = false,
 758                      bool class_unload = false,
 759                      bool skip_header = false) :
 760     _method_cb(writer, class_unload, skip_header),
 761     _klass_cb(writer, class_unload, skip_header),
 762     _method_used_predicate(current_epoch),
 763     _method_flag_predicate(current_epoch) {}
 764 
 765   bool operator()(KlassPtr klass) {
 766     if (_method_used_predicate(klass)) {
 767       const InstanceKlass* ik = InstanceKlass::cast(klass);
 768       const int len = ik->methods()->length();
 769       Filter filter(ik->previous_versions() != NULL ? len : 0);
 770       while (ik != NULL) {
 771         for (int i = 0; i < len; ++i) {
 772           MethodPtr method = ik->methods()->at(i);
 773           if (_method_flag_predicate(method) && filter(i)) {
 774             _method_cb(method);
 775           }
 776         }
 777         // There can be multiple versions of the same method running
 778         // due to redefinition. Need to inspect the complete set of methods.
 779         ik = ik->previous_versions();
 780       }
 781     }
 782     return _klass_cb(klass);
 783   }
 784 
 785   int count() const { return _method_cb.count(); }
 786   void add(int count) { _method_cb.add(count); }
 787 };
 788 
 789 template <typename T, template <typename> class Impl>
 790 class Wrapper {
 791   Impl<T> _t;
 792  public:
 793   Wrapper(JfrCheckpointWriter*, bool, bool) : _t() {}
 794   bool operator()(T const& value) {
 795     return _t(value);
 796   }
 797 };
 798 
 799 template <typename T>
 800 class EmptyStub {
 801  public:
 802   bool operator()(T const& value) { return true; }
 803 };
 804 
 805 typedef SerializePredicate<MethodPtr> MethodPredicate;
 806 typedef JfrPredicatedTypeWriterImplHost<MethodPtr, MethodPredicate, write__method> MethodWriterImplTarget;
 807 typedef Wrapper<KlassPtr, EmptyStub> KlassCallbackStub;
 808 typedef JfrTypeWriterHost<MethodWriterImplTarget, TYPE_METHOD> MethodWriterImpl;
 809 typedef MethodIteratorHost<MethodWriterImpl, KlassCallbackStub, BitMapFilter, false> MethodWriter;
 810 
 811 typedef LeakPredicate<MethodPtr> LeakMethodPredicate;
 812 typedef JfrPredicatedTypeWriterImplHost<MethodPtr, LeakMethodPredicate, write__method__leakp> LeakMethodWriterImplTarget;
 813 typedef JfrTypeWriterHost<LeakMethodWriterImplTarget, TYPE_METHOD> LeakMethodWriterImpl;
 814 typedef MethodIteratorHost<LeakMethodWriterImpl, KlassCallbackStub, BitMapFilter, true> LeakMethodWriter;
 815 typedef MethodIteratorHost<LeakMethodWriterImpl, KlassCallbackStub, BitMapFilter, true> LeakMethodWriter;
 816 typedef CompositeFunctor<KlassPtr, LeakMethodWriter, MethodWriter> CompositeMethodWriter;
 817 
 818 static void write_methods() {
 819   assert(_writer != NULL, "invariant");
 820   MethodWriter mw(_writer, current_epoch(), _class_unload);
 821   if (_leakp_writer == NULL) {
 822     _artifacts->iterate_klasses(mw);
 823   } else {
 824     LeakMethodWriter lpmw(_leakp_writer, current_epoch(), _class_unload);
 825     CompositeMethodWriter cmw(&lpmw, &mw);
 826     _artifacts->iterate_klasses(cmw);
 827   }
 828   _artifacts->tally(mw);
 829 }
 830 
 831 template <>
 832 void set_serialized<JfrSymbolId::SymbolEntry>(SymbolEntryPtr ptr) {
 833   assert(ptr != NULL, "invariant");
 834   ptr->set_serialized();
 835   assert(ptr->is_serialized(), "invariant");
 836 }
 837 
 838 template <>
 839 void set_serialized<JfrSymbolId::CStringEntry>(CStringEntryPtr ptr) {
 840   assert(ptr != NULL, "invariant");
 841   ptr->set_serialized();
 842   assert(ptr->is_serialized(), "invariant");
 843 }
 844 
 845 static int write_symbol(JfrCheckpointWriter* writer, SymbolEntryPtr entry, bool leakp) {
 846   assert(writer != NULL, "invariant");
 847   assert(entry != NULL, "invariant");
 848   ResourceMark rm;
 849   writer->write(create_symbol_id(entry->id()));
 850   writer->write(entry->value()->as_C_string());
 851   return 1;
 852 }
 853 
 854 int write__symbol(JfrCheckpointWriter* writer, const void* e) {
 855   assert(e != NULL, "invariant");
 856   SymbolEntryPtr entry = (SymbolEntryPtr)e;
 857   set_serialized(entry);
 858   return write_symbol(writer, entry, false);
 859 }
 860 
 861 int write__symbol__leakp(JfrCheckpointWriter* writer, const void* e) {
 862   assert(e != NULL, "invariant");
 863   SymbolEntryPtr entry = (SymbolEntryPtr)e;
 864   return write_symbol(writer, entry, true);
 865 }
 866 
 867 static int write_cstring(JfrCheckpointWriter* writer, CStringEntryPtr entry, bool leakp) {
 868   assert(writer != NULL, "invariant");
 869   assert(entry != NULL, "invariant");
 870   writer->write(create_symbol_id(entry->id()));
 871   writer->write(entry->value());
 872   return 1;
 873 }
 874 
 875 int write__cstring(JfrCheckpointWriter* writer, const void* e) {
 876   assert(e != NULL, "invariant");
 877   CStringEntryPtr entry = (CStringEntryPtr)e;
 878   set_serialized(entry);
 879   return write_cstring(writer, entry, false);
 880 }
 881 
 882 int write__cstring__leakp(JfrCheckpointWriter* writer, const void* e) {
 883   assert(e != NULL, "invariant");
 884   CStringEntryPtr entry = (CStringEntryPtr)e;
 885   return write_cstring(writer, entry, true);
 886 }
 887 
 888 typedef SymbolPredicate<SymbolEntryPtr, false> SymPredicate;
 889 typedef JfrPredicatedTypeWriterImplHost<SymbolEntryPtr, SymPredicate, write__symbol> SymbolEntryWriterImpl;
 890 typedef JfrTypeWriterHost<SymbolEntryWriterImpl, TYPE_SYMBOL> SymbolEntryWriter;
 891 typedef SymbolPredicate<CStringEntryPtr, false> CStringPredicate;
 892 typedef JfrPredicatedTypeWriterImplHost<CStringEntryPtr, CStringPredicate, write__cstring> CStringEntryWriterImpl;
 893 typedef JfrTypeWriterHost<CStringEntryWriterImpl, TYPE_SYMBOL> CStringEntryWriter;
 894 
 895 typedef SymbolPredicate<SymbolEntryPtr, true> LeakSymPredicate;
 896 typedef JfrPredicatedTypeWriterImplHost<SymbolEntryPtr, LeakSymPredicate, write__symbol__leakp> LeakSymbolEntryWriterImpl;
 897 typedef JfrTypeWriterHost<LeakSymbolEntryWriterImpl, TYPE_SYMBOL> LeakSymbolEntryWriter;
 898 typedef CompositeFunctor<SymbolEntryPtr, LeakSymbolEntryWriter, SymbolEntryWriter> CompositeSymbolWriter;
 899 typedef SymbolPredicate<CStringEntryPtr, true> LeakCStringPredicate;
 900 typedef JfrPredicatedTypeWriterImplHost<CStringEntryPtr, LeakCStringPredicate, write__cstring__leakp> LeakCStringEntryWriterImpl;
 901 typedef JfrTypeWriterHost<LeakCStringEntryWriterImpl, TYPE_SYMBOL> LeakCStringEntryWriter;
 902 typedef CompositeFunctor<CStringEntryPtr, LeakCStringEntryWriter, CStringEntryWriter> CompositeCStringWriter;
 903 
 904 static void write_symbols_with_leakp() {
 905   assert(_leakp_writer != NULL, "invariant");
 906   SymbolEntryWriter sw(_writer, _class_unload);
 907   LeakSymbolEntryWriter lsw(_leakp_writer, _class_unload);
 908   CompositeSymbolWriter csw(&lsw, &sw);
 909   _artifacts->iterate_symbols(csw);
 910   CStringEntryWriter ccsw(_writer, _class_unload, true); // skip header
 911   LeakCStringEntryWriter lccsw(_leakp_writer, _class_unload, true); // skip header
 912   CompositeCStringWriter cccsw(&lccsw, &ccsw);
 913   _artifacts->iterate_cstrings(cccsw);
 914   sw.add(ccsw.count());
 915   lsw.add(lccsw.count());
 916   _artifacts->tally(sw);
 917 }
 918 
 919 static void write_symbols() {
 920   assert(_writer != NULL, "invariant");
 921   if (_leakp_writer != NULL) {
 922     write_symbols_with_leakp();
 923     return;
 924   }
 925   SymbolEntryWriter sw(_writer, _class_unload);
 926   _artifacts->iterate_symbols(sw);
 927   CStringEntryWriter csw(_writer, _class_unload, true); // skip header
 928   _artifacts->iterate_cstrings(csw);
 929   sw.add(csw.count());
 930   _artifacts->tally(sw);
 931 }
 932 
 933 typedef Wrapper<KlassPtr, ClearArtifact> ClearKlassBits;
 934 typedef Wrapper<MethodPtr, ClearArtifact> ClearMethodFlag;
 935 typedef MethodIteratorHost<ClearMethodFlag, ClearKlassBits, AlwaysTrue, false> ClearKlassAndMethods;
 936 
 937 static bool clear_artifacts = false;
 938 
 939 static void clear_klasses_and_methods() {
 940   ClearKlassAndMethods clear(_writer);
 941   _artifacts->iterate_klasses(clear);
 942 }
 943 
 944 static size_t teardown() {
 945   assert(_artifacts != NULL, "invariant");
 946   const size_t total_count = _artifacts->total_count();
 947   if (previous_epoch()) {
 948     clear_klasses_and_methods();
 949     clear_artifacts = true;
 950     ++checkpoint_id;
 951   }
 952   return total_count;
 953 }
 954 
 955 static void setup(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer, bool class_unload, bool flushpoint) {
 956   _writer = writer;
 957   _leakp_writer = leakp_writer;
 958   _class_unload = class_unload;
 959   _flushpoint = flushpoint;
 960   if (_artifacts == NULL) {
 961     _artifacts = new JfrArtifactSet(class_unload);
 962   } else {
 963     _artifacts->initialize(class_unload, clear_artifacts);
 964   }
 965   clear_artifacts = false;
 966   assert(_artifacts != NULL, "invariant");
 967   assert(!_artifacts->has_klass_entries(), "invariant");
 968 }
 969 
 970 /**
 971  * Write all "tagged" (in-use) constant artifacts and their dependencies.
 972  */
 973 size_t JfrTypeSet::serialize(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer, bool class_unload, bool flushpoint) {
 974   assert(writer != NULL, "invariant");
 975   ResourceMark rm;
 976   setup(writer, leakp_writer, class_unload, flushpoint);
 977   // write order is important because an individual write step
 978   // might tag an artifact to be written in a subsequent step
 979   if (!write_klasses()) {
 980     return 0;
 981   }
 982   write_packages();
 983   write_modules();
 984   write_classloaders();
 985   write_methods();
 986   write_symbols();
 987   return teardown();
 988 }
 989 
 990 /**
 991  * Clear all tags from the previous epoch.
 992  */
 993 void JfrTypeSet::clear() {
 994   clear_artifacts = true;
 995   setup(NULL, NULL, false, false);
 996   register_klasses();
 997   clear_packages();
 998   clear_modules();
 999   clear_classloaders();
1000   clear_klasses_and_methods();
1001 }