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