src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp
branchJEP-349-branch
changeset 57870 00860d9caf4d
parent 57360 5d043a159d5c
child 57983 a57907813a83
equal deleted inserted replaced
57862:84ef29ccac56 57870:00860d9caf4d
    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 
       
    56 // incremented on each rotation
       
    57 static u8 checkpoint_id = 1;
       
    58 
       
    59 // creates a unique id by combining a checkpoint relative symbol id (2^24)
       
    60 // with the current checkpoint id (2^40)
       
    61 #define CREATE_SYMBOL_ID(sym_id) (((u8)((checkpoint_id << 24) | sym_id)))
       
    62 
       
    63 static traceid create_symbol_id(traceid artifact_id) {
       
    64   return artifact_id != 0 ? CREATE_SYMBOL_ID(artifact_id) : 0;
       
    65 }
       
    66 
       
    67 static JfrCheckpointWriter* _writer = NULL;
       
    68 static bool _class_unload = false;
       
    69 static bool _flushpoint = false;
       
    70 static JfrArtifactSet* _artifacts = NULL;
       
    71 static JfrArtifactClosure* _subsystem_callback = NULL;
       
    72 
       
    73 static bool current_epoch() {
       
    74   return _class_unload || _flushpoint;
       
    75 }
       
    76 
       
    77 static bool previous_epoch() {
       
    78   return !current_epoch();
       
    79 }
       
    80 
       
    81 static bool is_complete() {
       
    82   return !_artifacts->has_klass_entries() && current_epoch();
       
    83 }
       
    84 
       
    85 static traceid mark_symbol(KlassPtr klass) {
       
    86   return klass != NULL ? create_symbol_id(_artifacts->mark(klass)) : 0;
       
    87 }
       
    88 
       
    89 static traceid mark_symbol(Symbol* symbol) {
       
    90   return symbol != NULL ? create_symbol_id(_artifacts->mark(symbol)) : 0;
       
    91 }
       
    92 
       
    93 template <typename T>
       
    94 static traceid artifact_id(const T* ptr) {
       
    95   assert(ptr != NULL, "invariant");
       
    96   return TRACE_ID(ptr);
       
    97 }
       
    98 
       
    99 static traceid package_id(KlassPtr klass) {
       
   100   assert(klass != NULL, "invariant");
       
   101   PkgPtr pkg_entry = klass->package();
       
   102   return pkg_entry != NULL ? artifact_id(pkg_entry) : 0;
       
   103 }
       
   104 
    66 static traceid module_id(PkgPtr pkg) {
   105 static traceid module_id(PkgPtr pkg) {
    67   assert(pkg != NULL, "invariant");
   106   assert(pkg != NULL, "invariant");
    68   ModPtr module_entry = pkg->module();
   107   ModPtr module_entry = pkg->module();
    69   return module_entry != NULL && module_entry->is_named() ? TRACE_ID(module_entry) : 0;
   108   if (module_entry != NULL && module_entry->is_named()) {
    70 }
   109     SET_TRANSIENT(module_entry);
    71 
   110     return artifact_id(module_entry);
    72 static traceid package_id(KlassPtr klass) {
   111   }
       
   112   return 0;
       
   113 }
       
   114 
       
   115 static traceid method_id(KlassPtr klass, MethodPtr method) {
    73   assert(klass != NULL, "invariant");
   116   assert(klass != NULL, "invariant");
    74   PkgPtr pkg_entry = klass->package();
   117   assert(method != NULL, "invariant");
    75   return pkg_entry == NULL ? 0 : TRACE_ID(pkg_entry);
   118   return METHOD_ID(klass, method);
    76 }
   119 }
    77 
   120 
    78 static traceid cld_id(CldPtr cld) {
   121 static traceid cld_id(CldPtr cld) {
    79   assert(cld != NULL, "invariant");
   122   assert(cld != NULL, "invariant");
    80   return cld->is_unsafe_anonymous() ? 0 : TRACE_ID(cld);
   123   if (cld->is_unsafe_anonymous()) {
    81 }
   124     return 0;
    82 
   125   }
    83 static void tag_leakp_klass_artifacts(KlassPtr k, bool current_epoch) {
   126   SET_TRANSIENT(cld);
    84   assert(k != NULL, "invariant");
   127   return artifact_id(cld);
    85   PkgPtr pkg = k->package();
   128 }
    86   if (pkg != NULL) {
   129 
    87     tag_leakp_artifact(pkg, current_epoch);
   130 template <typename T>
    88     ModPtr module = pkg->module();
   131 static s4 get_flags(const T* ptr) {
    89     if (module != NULL) {
   132   assert(ptr != NULL, "invariant");
    90       tag_leakp_artifact(module, current_epoch);
   133   return ptr->access_flags().get_flags();
    91     }
   134 }
    92   }
   135 
    93   CldPtr cld = k->class_loader_data();
   136 template <typename T>
    94   assert(cld != NULL, "invariant");
   137 static void set_serialized(const T* ptr) {
    95   if (!cld->is_unsafe_anonymous()) {
   138   assert(ptr != NULL, "invariant");
    96     tag_leakp_artifact(cld, current_epoch);
   139   SET_SERIALIZED(ptr);
    97   }
   140   assert(IS_SERIALIZED(ptr), "invariant");
    98 }
   141 }
    99 
       
   100 class TagLeakpKlassArtifact {
       
   101   bool _current_epoch;
       
   102  public:
       
   103   TagLeakpKlassArtifact(bool current_epoch) : _current_epoch(current_epoch) {}
       
   104   bool operator()(KlassPtr klass) {
       
   105     if (_current_epoch) {
       
   106       if (LEAKP_USED_THIS_EPOCH(klass)) {
       
   107         tag_leakp_klass_artifacts(klass, _current_epoch);
       
   108       }
       
   109     } else {
       
   110       if (LEAKP_USED_PREV_EPOCH(klass)) {
       
   111         tag_leakp_klass_artifacts(klass, _current_epoch);
       
   112       }
       
   113     }
       
   114     return true;
       
   115   }
       
   116 };
       
   117 
   142 
   118 /*
   143 /*
   119  * In C++03, functions used as template parameters must have external linkage;
   144  * 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
   145  * this restriction was removed in C++11. Change back to "static" and
   121  * rename functions when C++11 becomes available.
   146  * rename functions when C++11 becomes available.
   122  *
   147  *
   123  * The weird naming is an effort to decrease the risk of name clashes.
   148  * The weird naming is an effort to decrease the risk of name clashes.
   124  */
   149  */
   125 
   150 
   126 int write__artifact__klass(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, KlassPtr klass) {
   151 int write__klass(JfrCheckpointWriter* writer, const void* k) {
   127   assert(writer != NULL, "invariant");
   152   assert(writer != NULL, "invariant");
   128   assert(artifacts != NULL, "invariant");
   153   assert(_artifacts != NULL, "invariant");
   129   assert(klass != NULL, "invariant");
   154   assert(k != NULL, "invariant");
       
   155   KlassPtr klass = (KlassPtr)k;
   130   traceid pkg_id = 0;
   156   traceid pkg_id = 0;
   131   KlassPtr theklass = klass;
   157   KlassPtr theklass = klass;
   132   if (theklass->is_objArray_klass()) {
   158   if (theklass->is_objArray_klass()) {
   133     const ObjArrayKlass* obj_arr_klass = ObjArrayKlass::cast(klass);
   159     const ObjArrayKlass* obj_arr_klass = ObjArrayKlass::cast(klass);
   134     theklass = obj_arr_klass->bottom_klass();
   160     theklass = obj_arr_klass->bottom_klass();
   136   if (theklass->is_instance_klass()) {
   162   if (theklass->is_instance_klass()) {
   137     pkg_id = package_id(theklass);
   163     pkg_id = package_id(theklass);
   138   } else {
   164   } else {
   139     assert(theklass->is_typeArray_klass(), "invariant");
   165     assert(theklass->is_typeArray_klass(), "invariant");
   140   }
   166   }
   141   const traceid symbol_id = artifacts->mark(klass);
   167   writer->write(artifact_id(klass));
   142   assert(symbol_id > 0, "need to have an address for symbol!");
       
   143   writer->write(TRACE_ID(klass));
       
   144   writer->write(cld_id(klass->class_loader_data()));
   168   writer->write(cld_id(klass->class_loader_data()));
   145   writer->write((traceid)CREATE_SYMBOL_ID(symbol_id));
   169   writer->write(mark_symbol(klass));
   146   writer->write(pkg_id);
   170   writer->write(pkg_id);
   147   writer->write((s4)klass->access_flags().get_flags());
   171   writer->write(get_flags(klass));
       
   172   set_serialized(klass);
   148   return 1;
   173   return 1;
   149 }
   174 }
   150 
   175 
   151 int write__artifact__klass__leakp(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* k) {
   176 static void do_implied(Klass* klass) {
   152   assert(k != NULL, "invariant");
       
   153   KlassPtr klass = (KlassPtr)k;
       
   154   return write__artifact__klass(writer, artifacts, klass);
       
   155 }
       
   156 
       
   157 int write__artifact__klass__serialize(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* k) {
       
   158   assert(k != NULL, "invariant");
       
   159   KlassPtr klass = (KlassPtr)k;
       
   160   int result = write__artifact__klass(writer, artifacts, klass);
       
   161   if (IS_NOT_SERIALIZED(klass)) {
       
   162     SET_SERIALIZED(klass);
       
   163   }
       
   164   assert(IS_SERIALIZED(klass), "invariant");
       
   165   return result;
       
   166 }
       
   167 
       
   168 typedef LeakPredicate<KlassPtr> LeakKlassPredicate;
       
   169 typedef SerializePredicate<KlassPtr> KlassPredicate;
       
   170 typedef JfrPredicatedArtifactWriterImplHost<KlassPtr, LeakKlassPredicate, write__artifact__klass__leakp> LeakKlassWriterImpl;
       
   171 typedef JfrArtifactWriterHost<LeakKlassWriterImpl, TYPE_CLASS> LeakKlassWriter;
       
   172 typedef JfrPredicatedArtifactWriterImplHost<KlassPtr, KlassPredicate, write__artifact__klass__serialize> KlassWriterImpl;
       
   173 typedef JfrArtifactWriterHost<KlassWriterImpl, TYPE_CLASS> KlassWriter;
       
   174 
       
   175 int write__artifact__method(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, MethodPtr method) {
       
   176   assert(writer != NULL, "invariant");
       
   177   assert(artifacts != NULL, "invariant");
       
   178   const traceid method_name_symbol_id = artifacts->mark(method->name());
       
   179   assert(method_name_symbol_id > 0, "invariant");
       
   180   const traceid method_sig_symbol_id = artifacts->mark(method->signature());
       
   181   assert(method_sig_symbol_id > 0, "invariant");
       
   182   KlassPtr klass = method->method_holder();
       
   183   assert(klass != NULL, "invariant");
   177   assert(klass != NULL, "invariant");
   184   assert(METHOD_USED_ANY_EPOCH(klass), "invariant");
   178   if (klass->is_subclass_of(SystemDictionary::ClassLoader_klass()) || klass == SystemDictionary::Object_klass()) {
   185   writer->write((u8)METHOD_ID(klass, method));
   179     _subsystem_callback->do_artifact(klass);
   186   writer->write((u8)TRACE_ID(klass));
   180   }
   187   writer->write((u8)CREATE_SYMBOL_ID(method_name_symbol_id));
   181 }
   188   writer->write((u8)CREATE_SYMBOL_ID(method_sig_symbol_id));
   182 
   189   writer->write((u2)method->access_flags().get_flags());
   183 static void do_unloaded_klass(Klass* klass) {
   190   writer->write(const_cast<Method*>(method)->is_hidden() ? (u1)1 : (u1)0);
       
   191   return 1;
       
   192 }
       
   193 
       
   194 int write__artifact__method__leakp(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* m) {
       
   195   assert(m != NULL, "invariant");
       
   196   MethodPtr method = (MethodPtr)m;
       
   197   return write__artifact__method(writer, artifacts, method);
       
   198 }
       
   199 
       
   200 int write__artifact__method__serialize(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* m) {
       
   201   assert(m != NULL, "invariant");
       
   202   MethodPtr method = (MethodPtr)m;
       
   203   int result = write__artifact__method(writer, artifacts, method);
       
   204   if (METHOD_NOT_SERIALIZED(method)) {
       
   205     SET_METHOD_SERIALIZED(method);
       
   206   }
       
   207   assert(IS_METHOD_SERIALIZED(method), "invariant");
       
   208   return result;
       
   209 }
       
   210 
       
   211 typedef JfrArtifactWriterImplHost<MethodPtr, write__artifact__method__leakp> LeakpMethodWriterImplTarget;
       
   212 typedef JfrArtifactWriterHost<LeakpMethodWriterImplTarget, TYPE_METHOD> LeakpMethodWriterImpl;
       
   213 typedef SerializePredicate<MethodPtr> MethodPredicate;
       
   214 typedef JfrPredicatedArtifactWriterImplHost<MethodPtr, MethodPredicate, write__artifact__method__serialize> MethodWriterImplTarget;
       
   215 typedef JfrArtifactWriterHost<MethodWriterImplTarget, TYPE_METHOD> MethodWriterImpl;
       
   216 
       
   217 int write__artifact__package(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, PkgPtr pkg) {
       
   218   assert(writer != NULL, "invariant");
       
   219   assert(artifacts != NULL, "invariant");
       
   220   assert(pkg != NULL, "invariant");
       
   221   Symbol* const pkg_name = pkg->name();
       
   222   const traceid package_name_symbol_id = pkg_name != NULL ? artifacts->mark(pkg_name) : 0;
       
   223   assert(package_name_symbol_id > 0, "invariant");
       
   224   writer->write((traceid)TRACE_ID(pkg));
       
   225   writer->write((traceid)CREATE_SYMBOL_ID(package_name_symbol_id));
       
   226   writer->write(module_id(pkg));
       
   227   writer->write((bool)pkg->is_exported());
       
   228   return 1;
       
   229 }
       
   230 
       
   231 int write__artifact__package__leakp(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* p) {
       
   232   assert(p != NULL, "invariant");
       
   233   PkgPtr pkg = (PkgPtr)p;
       
   234   return write__artifact__package(writer, artifacts, pkg);
       
   235 }
       
   236 
       
   237 int write__artifact__package__serialize(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* p) {
       
   238   assert(p != NULL, "invariant");
       
   239   PkgPtr pkg = (PkgPtr)p;
       
   240   int result = write__artifact__package(writer, artifacts, pkg);
       
   241   if (IS_NOT_SERIALIZED(pkg)) {
       
   242     SET_SERIALIZED(pkg);
       
   243   }
       
   244   assert(IS_SERIALIZED(pkg), "invariant");
       
   245   return result;
       
   246 }
       
   247 
       
   248 typedef LeakPredicate<PkgPtr> LeakPackagePredicate;
       
   249 //int _compare_pkg_ptr_(PkgPtr const& lhs, PkgPtr const& rhs) { return lhs > rhs ? 1 : (lhs < rhs) ? -1 : 0; }
       
   250 //typedef UniquePredicate<PkgPtr, _compare_pkg_ptr_> PackagePredicate;
       
   251 typedef SerializePredicate<PkgPtr> PackagePredicate;
       
   252 typedef JfrPredicatedArtifactWriterImplHost<PkgPtr, LeakPackagePredicate, write__artifact__package__leakp> LeakPackageWriterImpl;
       
   253 typedef JfrPredicatedArtifactWriterImplHost<PkgPtr, PackagePredicate, write__artifact__package__serialize> PackageWriterImpl;
       
   254 typedef JfrArtifactWriterHost<LeakPackageWriterImpl, TYPE_PACKAGE> LeakPackageWriter;
       
   255 typedef JfrArtifactWriterHost<PackageWriterImpl, TYPE_PACKAGE> PackageWriter;
       
   256 
       
   257 int write__artifact__module(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, ModPtr entry) {
       
   258   assert(entry != NULL, "invariant");
       
   259   Symbol* const module_name = entry->name();
       
   260   const traceid module_name_symbol_id = module_name != NULL ? artifacts->mark(module_name) : 0;
       
   261   Symbol* const module_version = entry->version();
       
   262   const traceid module_version_symbol_id = module_version != NULL ? artifacts->mark(module_version) : 0;
       
   263   Symbol* const module_location = entry->location();
       
   264   const traceid module_location_symbol_id = module_location != NULL ? artifacts->mark(module_location) : 0;
       
   265   writer->write((traceid)TRACE_ID(entry));
       
   266   writer->write(module_name_symbol_id == 0 ? (traceid)0 : (traceid)CREATE_SYMBOL_ID(module_name_symbol_id));
       
   267   writer->write(module_version_symbol_id == 0 ? (traceid)0 : (traceid)CREATE_SYMBOL_ID(module_version_symbol_id));
       
   268   writer->write(module_location_symbol_id == 0 ? (traceid)0 : (traceid)CREATE_SYMBOL_ID(module_location_symbol_id));
       
   269   writer->write(cld_id(entry->loader_data()));
       
   270   return 1;
       
   271 }
       
   272 
       
   273 int write__artifact__module__leakp(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* m) {
       
   274   assert(m != NULL, "invariant");
       
   275   ModPtr entry = (ModPtr)m;
       
   276   return write__artifact__module(writer, artifacts, entry);
       
   277 }
       
   278 
       
   279 int write__artifact__module__serialize(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* m) {
       
   280   assert(m != NULL, "invariant");
       
   281   ModPtr entry = (ModPtr)m;
       
   282   int result = write__artifact__module(writer, artifacts, entry);
       
   283   CldPtr cld = entry->loader_data();
       
   284   assert(cld != NULL, "invariant");
       
   285   if (IS_NOT_SERIALIZED(cld)) {
       
   286     if (!cld->is_unsafe_anonymous()) {
       
   287       SET_USED_PREV_EPOCH(cld);
       
   288     }
       
   289   }
       
   290   if (IS_NOT_SERIALIZED(entry)) {
       
   291     SET_SERIALIZED(entry);
       
   292   }
       
   293   assert(IS_SERIALIZED(entry), "invariant");
       
   294   return result;
       
   295 }
       
   296 
       
   297 typedef LeakPredicate<ModPtr> LeakModulePredicate;
       
   298 //int _compare_mod_ptr_(ModPtr const& lhs, ModPtr const& rhs) { return lhs > rhs ? 1 : (lhs < rhs) ? -1 : 0; }
       
   299 //typedef UniquePredicate<ModPtr, _compare_mod_ptr_> ModulePredicate;
       
   300 typedef SerializePredicate<ModPtr> ModulePredicate;
       
   301 typedef JfrPredicatedArtifactWriterImplHost<ModPtr, LeakModulePredicate, write__artifact__module__leakp> LeakModuleWriterImpl;
       
   302 typedef JfrPredicatedArtifactWriterImplHost<ModPtr, ModulePredicate, write__artifact__module__serialize> ModuleWriterImpl;
       
   303 typedef JfrArtifactWriterHost<LeakModuleWriterImpl, TYPE_MODULE> LeakModuleWriter;
       
   304 typedef JfrArtifactWriterHost<ModuleWriterImpl, TYPE_MODULE> ModuleWriter;
       
   305 
       
   306 int write__artifact__classloader(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, CldPtr cld) {
       
   307   assert(cld != NULL, "invariant");
       
   308   assert(!cld->is_unsafe_anonymous(), "invariant");
       
   309   const traceid cld_id = TRACE_ID(cld);
       
   310   // class loader type
       
   311   const Klass* class_loader_klass = cld->class_loader_klass();
       
   312   if (class_loader_klass == NULL) {
       
   313     // (primordial) boot class loader
       
   314     writer->write(cld_id); // class loader instance id
       
   315     writer->write((traceid)0);  // class loader type id (absence of)
       
   316     writer->write((traceid)CREATE_SYMBOL_ID(1)); // 1 maps to synthetic name -> "bootstrap"
       
   317   } else {
       
   318     Symbol* symbol_name = cld->name();
       
   319     const traceid symbol_name_id = symbol_name != NULL ? artifacts->mark(symbol_name) : 0;
       
   320     writer->write(cld_id); // class loader instance id
       
   321     writer->write(TRACE_ID(class_loader_klass)); // class loader type id
       
   322     writer->write(symbol_name_id == 0 ? (traceid)0 :
       
   323       (traceid)CREATE_SYMBOL_ID(symbol_name_id)); // class loader instance name
       
   324   }
       
   325   return 1;
       
   326 }
       
   327 
       
   328 int write__artifact__classloader__leakp(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* c) {
       
   329   assert(c != NULL, "invariant");
       
   330   CldPtr cld = (CldPtr)c;
       
   331   int result = write__artifact__classloader(writer, artifacts, cld);
       
   332   if (IS_NOT_LEAKP_SERIALIZED(cld)) {
       
   333     SET_LEAKP_SERIALIZED(cld);
       
   334   }
       
   335   assert(IS_LEAKP_SERIALIZED(cld), "invariant");
       
   336   return result;
       
   337 }
       
   338 
       
   339 int write__artifact__classloader__serialize(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* c) {
       
   340   assert(c != NULL, "invariant");
       
   341   CldPtr cld = (CldPtr)c;
       
   342   int result = write__artifact__classloader(writer, artifacts, cld);
       
   343   if (IS_NOT_SERIALIZED(cld)) {
       
   344     SET_SERIALIZED(cld);
       
   345   }
       
   346   assert(IS_SERIALIZED(cld), "invariant");
       
   347   return result;
       
   348 }
       
   349 
       
   350 typedef LeakSerializePredicate<CldPtr> LeakCldPredicate;
       
   351 //int _compare_cld_ptr_(CldPtr const& lhs, CldPtr const& rhs) { return lhs > rhs ? 1 : (lhs < rhs) ? -1 : 0; }
       
   352 //typedef UniquePredicate<CldPtr, _compare_cld_ptr_> CldPredicate;
       
   353 typedef SerializePredicate<CldPtr> CldPredicate;
       
   354 typedef JfrPredicatedArtifactWriterImplHost<CldPtr, LeakCldPredicate, write__artifact__classloader__leakp> LeakCldWriterImpl;
       
   355 typedef JfrPredicatedArtifactWriterImplHost<CldPtr, CldPredicate, write__artifact__classloader__serialize> CldWriterImpl;
       
   356 typedef JfrArtifactWriterHost<LeakCldWriterImpl, TYPE_CLASSLOADER> LeakCldWriter;
       
   357 typedef JfrArtifactWriterHost<CldWriterImpl, TYPE_CLASSLOADER> CldWriter;
       
   358 
       
   359 typedef const JfrSymbolId::SymbolEntry* SymbolEntryPtr;
       
   360 
       
   361 static int write__artifact__symbol__entry__(JfrCheckpointWriter* writer, SymbolEntryPtr entry) {
       
   362   assert(writer != NULL, "invariant");
       
   363   assert(entry != NULL, "invariant");
       
   364   ResourceMark rm;
       
   365   writer->write(CREATE_SYMBOL_ID(entry->id()));
       
   366   writer->write(entry->value()->as_C_string());
       
   367   return 1;
       
   368 }
       
   369 
       
   370 int write__artifact__symbol__entry(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* e) {
       
   371   assert(e != NULL, "invariant");
       
   372   return write__artifact__symbol__entry__(writer, (SymbolEntryPtr)e);
       
   373 }
       
   374 
       
   375 typedef JfrArtifactWriterImplHost<SymbolEntryPtr, write__artifact__symbol__entry> SymbolEntryWriterImpl;
       
   376 typedef JfrArtifactWriterHost<SymbolEntryWriterImpl, TYPE_SYMBOL> SymbolEntryWriter;
       
   377 
       
   378 typedef const JfrSymbolId::CStringEntry* CStringEntryPtr;
       
   379 
       
   380 static int write__artifact__cstring__entry__(JfrCheckpointWriter* writer, CStringEntryPtr entry) {
       
   381   assert(writer != NULL, "invariant");
       
   382   assert(entry != NULL, "invariant");
       
   383   writer->write(CREATE_SYMBOL_ID(entry->id()));
       
   384   writer->write(entry->value());
       
   385   return 1;
       
   386 }
       
   387 
       
   388 int write__artifact__cstring__entry(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* e) {
       
   389   assert(e != NULL, "invariant");
       
   390   return write__artifact__cstring__entry__(writer, (CStringEntryPtr)e);
       
   391 }
       
   392 
       
   393 typedef JfrArtifactWriterImplHost<CStringEntryPtr, write__artifact__cstring__entry> CStringEntryWriterImpl;
       
   394 typedef JfrArtifactWriterHost<CStringEntryWriterImpl, TYPE_SYMBOL> CStringEntryWriter;
       
   395 
       
   396 int write__artifact__klass__symbol(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* k) {
       
   397   assert(writer != NULL, "invariant");
       
   398   assert(artifacts != NULL, "invaiant");
       
   399   assert(k != NULL, "invariant");
       
   400   const InstanceKlass* const ik = (const InstanceKlass*)k;
       
   401   if (ik->is_unsafe_anonymous()) {
       
   402     CStringEntryPtr entry =
       
   403       artifacts->map_cstring(JfrSymbolId::unsafe_anonymous_klass_name_hash_code(ik));
       
   404     assert(entry != NULL, "invariant");
       
   405     return write__artifact__cstring__entry__(writer, entry);
       
   406   }
       
   407 
       
   408   SymbolEntryPtr entry = artifacts->map_symbol(JfrSymbolId::regular_klass_name_hash_code(ik));
       
   409   return write__artifact__symbol__entry__(writer, entry);
       
   410 }
       
   411 
       
   412 int _compare_traceid_(const traceid& lhs, const traceid& rhs) {
       
   413   return lhs > rhs ? 1 : (lhs < rhs) ? -1 : 0;
       
   414 }
       
   415 
       
   416 template <template <typename> class Predicate>
       
   417 class KlassSymbolWriterImpl {
       
   418  private:
       
   419   JfrCheckpointWriter* _writer;
       
   420   JfrArtifactSet* _artifacts;
       
   421   Predicate<KlassPtr> _predicate;
       
   422   MethodUsedPredicate<true> _method_used_predicate;
       
   423   MethodFlagPredicate _method_flag_predicate;
       
   424   UniquePredicate<traceid, _compare_traceid_> _unique_predicate;
       
   425 
       
   426   int klass_symbols(KlassPtr klass);
       
   427   int package_symbols(PkgPtr pkg);
       
   428   int module_symbols(ModPtr module);
       
   429   int class_loader_symbols(CldPtr cld);
       
   430   int method_symbols(KlassPtr klass);
       
   431 
       
   432  public:
       
   433   typedef KlassPtr Type;
       
   434   KlassSymbolWriterImpl(JfrCheckpointWriter* writer,
       
   435                         JfrArtifactSet* artifacts,
       
   436                         bool current_epoch) : _writer(writer),
       
   437                                              _artifacts(artifacts),
       
   438                                              _predicate(current_epoch),
       
   439                                              _method_used_predicate(current_epoch),
       
   440                                              _method_flag_predicate(current_epoch),
       
   441                                              _unique_predicate(current_epoch) {}
       
   442 
       
   443   int operator()(KlassPtr klass) {
       
   444     assert(klass != NULL, "invariant");
       
   445     int count = 0;
       
   446     if (_predicate(klass)) {
       
   447       count += klass_symbols(klass);
       
   448       PkgPtr pkg = klass->package();
       
   449       if (pkg != NULL) {
       
   450         count += package_symbols(pkg);
       
   451         ModPtr module = pkg->module();
       
   452         if (module != NULL && module->is_named()) {
       
   453           count += module_symbols(module);
       
   454         }
       
   455       }
       
   456       CldPtr cld = klass->class_loader_data();
       
   457       assert(cld != NULL, "invariant");
       
   458       if (!cld->is_unsafe_anonymous()) {
       
   459         count += class_loader_symbols(cld);
       
   460       }
       
   461       if (_method_used_predicate(klass)) {
       
   462         count += method_symbols(klass);
       
   463       }
       
   464     }
       
   465     return count;
       
   466   }
       
   467 };
       
   468 
       
   469 template <template <typename> class Predicate>
       
   470 int KlassSymbolWriterImpl<Predicate>::klass_symbols(KlassPtr klass) {
       
   471   assert(klass != NULL, "invariant");
       
   472   assert(_predicate(klass), "invariant");
       
   473   const InstanceKlass* const ik = (const InstanceKlass*)klass;
       
   474   if (ik->is_unsafe_anonymous()) {
       
   475     CStringEntryPtr entry =
       
   476       this->_artifacts->map_cstring(JfrSymbolId::unsafe_anonymous_klass_name_hash_code(ik));
       
   477     assert(entry != NULL, "invariant");
       
   478     return _unique_predicate(entry->id()) ? write__artifact__cstring__entry__(this->_writer, entry) : 0;
       
   479   }
       
   480   SymbolEntryPtr entry = this->_artifacts->map_symbol(ik->name());
       
   481   assert(entry != NULL, "invariant");
       
   482   return _unique_predicate(entry->id()) ? write__artifact__symbol__entry__(this->_writer, entry) : 0;
       
   483 }
       
   484 
       
   485 template <template <typename> class Predicate>
       
   486 int KlassSymbolWriterImpl<Predicate>::package_symbols(PkgPtr pkg) {
       
   487   assert(pkg != NULL, "invariant");
       
   488   SymbolPtr pkg_name = pkg->name();
       
   489   assert(pkg_name != NULL, "invariant");
       
   490   SymbolEntryPtr package_symbol = this->_artifacts->map_symbol(pkg_name);
       
   491   assert(package_symbol != NULL, "invariant");
       
   492   return _unique_predicate(package_symbol->id()) ? write__artifact__symbol__entry__(this->_writer, package_symbol) : 0;
       
   493 }
       
   494 
       
   495 template <template <typename> class Predicate>
       
   496 int KlassSymbolWriterImpl<Predicate>::module_symbols(ModPtr module) {
       
   497   assert(module != NULL, "invariant");
       
   498   assert(module->is_named(), "invariant");
       
   499   int count = 0;
       
   500   SymbolPtr sym = module->name();
       
   501   SymbolEntryPtr entry = NULL;
       
   502   if (sym != NULL) {
       
   503     entry = this->_artifacts->map_symbol(sym);
       
   504     assert(entry != NULL, "invariant");
       
   505     if (_unique_predicate(entry->id())) {
       
   506       count += write__artifact__symbol__entry__(this->_writer, entry);
       
   507     }
       
   508   }
       
   509   sym = module->version();
       
   510   if (sym != NULL) {
       
   511     entry = this->_artifacts->map_symbol(sym);
       
   512     assert(entry != NULL, "invariant");
       
   513     if (_unique_predicate(entry->id())) {
       
   514       count += write__artifact__symbol__entry__(this->_writer, entry);
       
   515     }
       
   516   }
       
   517   sym = module->location();
       
   518   if (sym != NULL) {
       
   519     entry = this->_artifacts->map_symbol(sym);
       
   520     assert(entry != NULL, "invariant");
       
   521     if (_unique_predicate(entry->id())) {
       
   522       count += write__artifact__symbol__entry__(this->_writer, entry);
       
   523     }
       
   524   }
       
   525   return count;
       
   526 }
       
   527 
       
   528 template <template <typename> class Predicate>
       
   529 int KlassSymbolWriterImpl<Predicate>::class_loader_symbols(CldPtr cld) {
       
   530   assert(cld != NULL, "invariant");
       
   531   assert(!cld->is_unsafe_anonymous(), "invariant");
       
   532   int count = 0;
       
   533   // class loader type
       
   534   const Klass* class_loader_klass = cld->class_loader_klass();
       
   535   if (class_loader_klass == NULL) {
       
   536     // (primordial) boot class loader
       
   537     CStringEntryPtr entry = this->_artifacts->map_cstring(0);
       
   538     assert(entry != NULL, "invariant");
       
   539     assert(strncmp(entry->literal(),
       
   540       BOOTSTRAP_LOADER_NAME,
       
   541       BOOTSTRAP_LOADER_NAME_LEN) == 0, "invariant");
       
   542     if (_unique_predicate(entry->id())) {
       
   543       count += write__artifact__cstring__entry__(this->_writer, entry);
       
   544     }
       
   545   } else {
       
   546     const Symbol* class_loader_name = cld->name();
       
   547     if (class_loader_name != NULL) {
       
   548       SymbolEntryPtr entry = this->_artifacts->map_symbol(class_loader_name);
       
   549       assert(entry != NULL, "invariant");
       
   550       if (_unique_predicate(entry->id())) {
       
   551         count += write__artifact__symbol__entry__(this->_writer, entry);
       
   552       }
       
   553     }
       
   554   }
       
   555   return count;
       
   556 }
       
   557 
       
   558 template <template <typename> class Predicate>
       
   559 int KlassSymbolWriterImpl<Predicate>::method_symbols(KlassPtr klass) {
       
   560   assert(_predicate(klass), "invariant");
       
   561   assert(_method_used_predicate(klass), "invariant");
       
   562   assert(METHOD_AND_CLASS_USED_ANY_EPOCH(klass), "invariant");
       
   563   int count = 0;
       
   564   const InstanceKlass* const ik = InstanceKlass::cast(klass);
       
   565   const int len = ik->methods()->length();
       
   566   for (int i = 0; i < len; ++i) {
       
   567     MethodPtr method = ik->methods()->at(i);
       
   568     if (_method_flag_predicate(method)) {
       
   569       SymbolEntryPtr entry = this->_artifacts->map_symbol(method->name());
       
   570       assert(entry != NULL, "invariant");
       
   571       if (_unique_predicate(entry->id())) {
       
   572         count += write__artifact__symbol__entry__(this->_writer, entry);
       
   573       }
       
   574       entry = this->_artifacts->map_symbol(method->signature());
       
   575       assert(entry != NULL, "invariant");
       
   576       if (_unique_predicate(entry->id())) {
       
   577         count += write__artifact__symbol__entry__(this->_writer, entry);
       
   578       }
       
   579     }
       
   580   }
       
   581   return count;
       
   582 }
       
   583 
       
   584 typedef KlassSymbolWriterImpl<LeakPredicate> LeakKlassSymbolWriterImpl;
       
   585 typedef JfrArtifactWriterHost<LeakKlassSymbolWriterImpl, TYPE_SYMBOL> LeakKlassSymbolWriter;
       
   586 
       
   587 class ClearKlassAndMethods {
       
   588  private:
       
   589   ClearArtifact<KlassPtr> _clear_klass_tag_bits;
       
   590   ClearArtifact<MethodPtr> _clear_method_flag;
       
   591   MethodUsedPredicate<false> _method_used_predicate;
       
   592 
       
   593  public:
       
   594   ClearKlassAndMethods(bool current_epoch) : _method_used_predicate(current_epoch) {}
       
   595   bool operator()(KlassPtr klass) {
       
   596     if (_method_used_predicate(klass)) {
       
   597       const InstanceKlass* ik = InstanceKlass::cast(klass);
       
   598       const int len = ik->methods()->length();
       
   599       for (int i = 0; i < len; ++i) {
       
   600         MethodPtr method = ik->methods()->at(i);
       
   601         _clear_method_flag(method);
       
   602       }
       
   603     }
       
   604     _clear_klass_tag_bits(klass);
       
   605     return true;
       
   606   }
       
   607 };
       
   608 
       
   609 typedef CompositeFunctor<KlassPtr,
       
   610                          TagLeakpKlassArtifact,
       
   611                          LeakKlassWriter> LeakpKlassArtifactTagging;
       
   612 
       
   613 typedef CompositeFunctor<KlassPtr,
       
   614                          LeakpKlassArtifactTagging,
       
   615                          KlassWriter> CompositeKlassWriter;
       
   616 
       
   617 typedef CompositeFunctor<KlassPtr,
       
   618                          CompositeKlassWriter,
       
   619                          KlassArtifactRegistrator> CompositeKlassWriterRegistration;
       
   620 
       
   621 typedef CompositeFunctor<KlassPtr,
       
   622                          KlassWriter,
       
   623                          KlassArtifactRegistrator> KlassWriterRegistration;
       
   624 
       
   625 typedef JfrArtifactCallbackHost<KlassPtr, KlassWriterRegistration> KlassCallback;
       
   626 typedef JfrArtifactCallbackHost<KlassPtr, CompositeKlassWriterRegistration> CompositeKlassCallback;
       
   627 
       
   628 /*
       
   629  * Composite operation
       
   630  *
       
   631  * TagLeakpKlassArtifact ->
       
   632  *   LeakpPredicate ->
       
   633  *     LeakpKlassWriter ->
       
   634  *       KlassPredicate ->
       
   635  *         KlassWriter ->
       
   636  *           KlassWriterRegistration
       
   637  */
       
   638 void JfrTypeSet::write_klass_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
       
   639   assert(!_artifacts->has_klass_entries(), "invariant");
       
   640   KlassArtifactRegistrator reg(_artifacts);
       
   641   KlassWriter kw(writer, _artifacts, current_epoch());
       
   642   KlassWriterRegistration kwr(&kw, &reg);
       
   643   if (leakp_writer == NULL) {
       
   644     KlassCallback callback(&kwr);
       
   645     _subsystem_callback = &callback;
       
   646     do_klasses();
       
   647     _artifacts->tally(kw);
       
   648     return;
       
   649   }
       
   650   TagLeakpKlassArtifact tagging(current_epoch());
       
   651   LeakKlassWriter lkw(leakp_writer, _artifacts, current_epoch());
       
   652   LeakpKlassArtifactTagging lpkat(&tagging, &lkw);
       
   653   CompositeKlassWriter ckw(&lpkat, &kw);
       
   654   CompositeKlassWriterRegistration ckwr(&ckw, &reg);
       
   655   CompositeKlassCallback callback(&ckwr);
       
   656   _subsystem_callback = &callback;
       
   657   do_klasses();
       
   658 }
       
   659 
       
   660 typedef CompositeFunctor<PkgPtr,
       
   661                          PackageWriter,
       
   662                          ClearArtifact<PkgPtr> > PackageWriterWithClear;
       
   663 
       
   664 typedef CompositeFunctor<PkgPtr,
       
   665                          PackageWriter,
       
   666                          UnTagArtifact<PkgPtr> > PackageWriterWithUnTag;
       
   667 typedef CompositeFunctor<PkgPtr,
       
   668                          LeakPackageWriter,
       
   669                          PackageWriter> CompositePackageWriter;
       
   670 
       
   671 typedef CompositeFunctor<PkgPtr,
       
   672                          CompositePackageWriter,
       
   673                          ClearArtifact<PkgPtr> > CompositePackageWriterWithClear;
       
   674 typedef CompositeFunctor<PkgPtr,
       
   675                          CompositePackageWriter,
       
   676                          UnTagArtifact<PkgPtr> > CompositePackageWriterWithUnTag;
       
   677 
       
   678 class PackageFieldSelector {
       
   679  public:
       
   680   typedef PkgPtr TypePtr;
       
   681   static TypePtr select(KlassPtr klass) {
       
   682     assert(klass != NULL, "invariant");
       
   683     return ((InstanceKlass*)klass)->package();
       
   684   }
       
   685 };
       
   686 
       
   687 typedef KlassToFieldEnvelope<PackageFieldSelector,
       
   688                              PackageWriterWithClear> KlassPackageWriterWithClear;
       
   689 
       
   690 typedef KlassToFieldEnvelope<PackageFieldSelector,
       
   691                              PackageWriterWithUnTag> KlassPackageWriterWithUnTag;
       
   692 typedef KlassToFieldEnvelope<PackageFieldSelector, PackageWriter> KlassPackageWriter;
       
   693 typedef KlassToFieldEnvelope<PackageFieldSelector, CompositePackageWriter> KlassCompositePackageWriter;
       
   694 typedef KlassToFieldEnvelope<PackageFieldSelector,
       
   695                              CompositePackageWriterWithClear> KlassCompositePackageWriterWithClear;
       
   696 
       
   697 typedef KlassToFieldEnvelope<PackageFieldSelector,
       
   698                              CompositePackageWriterWithUnTag> KlassCompositePackageWriterWithUnTag;
       
   699 typedef JfrArtifactCallbackHost<PkgPtr, PackageWriterWithClear> PackageCallback;
       
   700 typedef JfrArtifactCallbackHost<PkgPtr, CompositePackageWriterWithClear> CompositePackageCallback;
       
   701 
       
   702 static void write_package_constants_current_epoch(JfrArtifactSet* artifacts, JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
       
   703   assert(artifacts != NULL, "invariant");
       
   704   assert(artifacts->has_klass_entries(), "invariant");
       
   705   PackageWriter pw(writer, artifacts, true);
       
   706   if (leakp_writer == NULL) {
       
   707     KlassPackageWriter kpw(&pw);
       
   708     artifacts->iterate_klasses(kpw);
       
   709     artifacts->tally(pw);
       
   710   } else {
       
   711     LeakPackageWriter lpw(leakp_writer, artifacts, true);
       
   712     CompositePackageWriter cpw(&lpw, &pw);
       
   713     KlassCompositePackageWriter kcpw(&cpw);
       
   714     artifacts->iterate_klasses(kcpw);
       
   715   }
       
   716 }
       
   717 
       
   718 /*
       
   719  * Composite operation
       
   720  *
       
   721  * LeakpPackageWriter ->
       
   722  *   PackageWriter ->
       
   723  *     ClearArtifact<PackageEntry>
       
   724  *
       
   725  */
       
   726 void JfrTypeSet::write_package_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
       
   727   assert(_artifacts->has_klass_entries(), "invariant");
       
   728   if (current_epoch()) {
       
   729     write_package_constants_current_epoch(_artifacts, writer, leakp_writer);
       
   730     return;
       
   731   }
       
   732   assert(is_rotating(), "invariant");
       
   733   PackageWriter pw(writer, _artifacts, false);
       
   734   ClearArtifact<PkgPtr> clear;
       
   735   UnTagArtifact<PkgPtr> untag;
       
   736   if (leakp_writer == NULL) {
       
   737     PackageWriterWithUnTag kpw(&pw, &untag);
       
   738     KlassPackageWriterWithUnTag kpwwut(&kpw);
       
   739     _artifacts->iterate_klasses(kpwwut);
       
   740     PackageWriterWithClear pwwc(&pw, &clear);
       
   741     PackageCallback callback(&pwwc);
       
   742     _subsystem_callback = &callback;
       
   743     do_packages();
       
   744     return;
       
   745   }
       
   746   LeakPackageWriter lpw(leakp_writer, _artifacts, false);
       
   747   CompositePackageWriter cpw(&lpw, &pw);
       
   748   CompositePackageWriterWithUnTag cpwwut(&cpw, &untag);
       
   749   KlassCompositePackageWriterWithUnTag kcpw(&cpwwut);
       
   750   _artifacts->iterate_klasses(kcpw);
       
   751   CompositePackageWriterWithClear cpwwc(&cpw, &clear);
       
   752   CompositePackageCallback callback(&cpwwc);
       
   753   _subsystem_callback = &callback;
       
   754   do_packages();
       
   755 }
       
   756 
       
   757 typedef CompositeFunctor<ModPtr,
       
   758                          ModuleWriter,
       
   759                          ClearArtifact<ModPtr> > ModuleWriterWithClear;
       
   760 
       
   761 typedef CompositeFunctor<ModPtr,
       
   762                          ModuleWriter,
       
   763                          UnTagArtifact<ModPtr> > ModuleWriterWithUnTag;
       
   764 typedef CompositeFunctor<ModPtr,
       
   765                          LeakModuleWriter,
       
   766                          ModuleWriter> CompositeModuleWriter;
       
   767 
       
   768 typedef CompositeFunctor<ModPtr,
       
   769                          CompositeModuleWriter,
       
   770                          ClearArtifact<ModPtr> > CompositeModuleWriterWithClear;
       
   771 typedef CompositeFunctor<ModPtr,
       
   772                          CompositeModuleWriter,
       
   773                          UnTagArtifact<ModPtr> > CompositeModuleWriterWithUnTag;
       
   774 
       
   775 typedef JfrArtifactCallbackHost<ModPtr, ModuleWriterWithClear> ModuleCallback;
       
   776 typedef JfrArtifactCallbackHost<ModPtr, CompositeModuleWriterWithClear> CompositeModuleCallback;
       
   777 
       
   778 class ModuleFieldSelector {
       
   779  public:
       
   780   typedef ModPtr TypePtr;
       
   781   static TypePtr select(KlassPtr klass) {
       
   782     assert(klass != NULL, "invariant");
       
   783     PkgPtr pkg = klass->package();
       
   784     return pkg != NULL ? pkg->module() : NULL;
       
   785   }
       
   786 };
       
   787 
       
   788 typedef KlassToFieldEnvelope<ModuleFieldSelector,
       
   789                              ModuleWriterWithClear> KlassModuleWriterWithClear;
       
   790 
       
   791 typedef KlassToFieldEnvelope<ModuleFieldSelector,
       
   792                              ModuleWriterWithUnTag> KlassModuleWriterWithUnTag;
       
   793 typedef KlassToFieldEnvelope<ModuleFieldSelector, ModuleWriter> KlassModuleWriter;
       
   794 typedef KlassToFieldEnvelope<ModuleFieldSelector,  CompositeModuleWriter> KlassCompositeModuleWriter;
       
   795 typedef KlassToFieldEnvelope<ModuleFieldSelector,
       
   796                              CompositeModuleWriterWithClear> KlassCompositeModuleWriterWithClear;
       
   797 
       
   798 typedef KlassToFieldEnvelope<ModuleFieldSelector,
       
   799                              CompositeModuleWriterWithUnTag> KlassCompositeModuleWriterWithUnTag;
       
   800 
       
   801 static void write_module_constants_current_epoch(JfrArtifactSet* artifacts, JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
       
   802   assert(artifacts != NULL, "invariant");
       
   803   assert(artifacts->has_klass_entries(), "invariant");
       
   804   ModuleWriter mw(writer, artifacts, true);
       
   805   if (leakp_writer == NULL) {
       
   806     KlassModuleWriter kmw(&mw);
       
   807     artifacts->iterate_klasses(kmw);
       
   808     artifacts->tally(mw);
       
   809   } else {
       
   810     LeakModuleWriter lmw(leakp_writer, artifacts, true);
       
   811     CompositeModuleWriter cmw(&lmw, &mw);
       
   812     KlassCompositeModuleWriter kcmw(&cmw);
       
   813     artifacts->iterate_klasses(kcmw);
       
   814   }
       
   815 }
       
   816 
       
   817 /*
       
   818  * Composite operation
       
   819  *
       
   820  * LeakpModuleWriter ->
       
   821  *   ModuleWriter ->
       
   822  *     ClearArtifact<ModuleEntry>
       
   823  */
       
   824 void JfrTypeSet::write_module_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
       
   825   assert(_artifacts->has_klass_entries(), "invariant");
       
   826   if (current_epoch()) {
       
   827     write_module_constants_current_epoch(_artifacts, writer, leakp_writer);
       
   828     return;
       
   829   }
       
   830   assert(is_rotating(), "invariant");
       
   831   ClearArtifact<ModPtr> clear;
       
   832   UnTagArtifact<ModPtr> untag;
       
   833   ModuleWriter mw(writer, _artifacts, false);
       
   834   if (leakp_writer == NULL) {
       
   835     ModuleWriterWithUnTag kpw(&mw, &untag);
       
   836     KlassModuleWriterWithUnTag kmwwut(&kpw);
       
   837     _artifacts->iterate_klasses(kmwwut);
       
   838     ModuleWriterWithClear mwwc(&mw, &clear);
       
   839     ModuleCallback callback(&mwwc);
       
   840     _subsystem_callback = &callback;
       
   841     do_modules();
       
   842     return;
       
   843   }
       
   844   LeakModuleWriter lmw(leakp_writer, _artifacts, false);
       
   845   CompositeModuleWriter cmw(&lmw, &mw);
       
   846   CompositeModuleWriterWithUnTag cmwwut(&cmw, &untag);
       
   847   KlassCompositeModuleWriterWithUnTag kcmw(&cmwwut);
       
   848   _artifacts->iterate_klasses(kcmw);
       
   849   CompositeModuleWriterWithClear cmwwc(&cmw, &clear);
       
   850   CompositeModuleCallback callback(&cmwwc);
       
   851   _subsystem_callback = &callback;
       
   852   do_modules();
       
   853 }
       
   854 
       
   855 typedef CompositeFunctor<CldPtr, CldWriter, ClearArtifact<CldPtr> > CldWriterWithClear;
       
   856 typedef CompositeFunctor<CldPtr, CldWriter, UnTagArtifact<CldPtr> > CldWriterWithUnTag;
       
   857 typedef CompositeFunctor<CldPtr, LeakCldWriter, CldWriter> CompositeCldWriter;
       
   858 typedef CompositeFunctor<CldPtr, CompositeCldWriter, ClearArtifact<CldPtr> > CompositeCldWriterWithClear;
       
   859 typedef CompositeFunctor<CldPtr, CompositeCldWriter, UnTagArtifact<CldPtr> > CompositeCldWriterWithUnTag;
       
   860 typedef JfrArtifactCallbackHost<CldPtr, CldWriterWithClear> CldCallback;
       
   861 typedef JfrArtifactCallbackHost<CldPtr, CompositeCldWriterWithClear> CompositeCldCallback;
       
   862 
       
   863 class CldFieldSelector {
       
   864  public:
       
   865   typedef CldPtr TypePtr;
       
   866   static TypePtr select(KlassPtr klass) {
       
   867     assert(klass != NULL, "invariant");
       
   868     CldPtr cld = klass->class_loader_data();
       
   869     return cld->is_unsafe_anonymous() ? NULL : cld;
       
   870   }
       
   871 };
       
   872 
       
   873 typedef KlassToFieldEnvelope<CldFieldSelector, CldWriter> KlassCldWriter;
       
   874 typedef KlassToFieldEnvelope<CldFieldSelector, CldWriterWithClear> KlassCldWriterWithClear;
       
   875 typedef KlassToFieldEnvelope<CldFieldSelector, CldWriterWithUnTag> KlassCldWriterWithUnTag;
       
   876 typedef KlassToFieldEnvelope<CldFieldSelector, CompositeCldWriter> KlassCompositeCldWriter;
       
   877 typedef KlassToFieldEnvelope<CldFieldSelector, CompositeCldWriterWithClear> KlassCompositeCldWriterWithClear;
       
   878 typedef KlassToFieldEnvelope<CldFieldSelector, CompositeCldWriterWithUnTag> KlassCompositeCldWriterWithUnTag;
       
   879 
       
   880 static void write_class_loader_constants_current_epoch(JfrArtifactSet* artifacts, JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
       
   881   assert(artifacts != NULL, "invariant");
       
   882   assert(artifacts->has_klass_entries(), "invariant");
       
   883   CldWriter cldw(writer, artifacts, true);
       
   884   if (leakp_writer == NULL) {
       
   885     KlassCldWriter kcw(&cldw);
       
   886     artifacts->iterate_klasses(kcw);
       
   887     artifacts->tally(cldw);
       
   888   } else {
       
   889     LeakCldWriter lcldw(leakp_writer, artifacts, true);
       
   890     CompositeCldWriter ccldw(&lcldw, &cldw);
       
   891     KlassCompositeCldWriter kccldw(&ccldw);
       
   892     artifacts->iterate_klasses(kccldw);
       
   893   }
       
   894 }
       
   895 
       
   896 /*
       
   897  * Composite operation
       
   898  *
       
   899  * LeakpClassLoaderWriter ->
       
   900  *   ClassLoaderWriter ->
       
   901  *     ClearArtifact<ClassLoaderData>
       
   902  */
       
   903 void JfrTypeSet::write_class_loader_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
       
   904   assert(_artifacts->has_klass_entries(), "invariant");
       
   905   if (current_epoch()) {
       
   906     write_class_loader_constants_current_epoch(_artifacts, writer, leakp_writer);
       
   907     return;
       
   908   }
       
   909   assert(is_rotating(), "invariant");
       
   910   ClearArtifact<CldPtr> clear;
       
   911   UnTagArtifact<CldPtr> untag;
       
   912   CldWriter cldw(writer, _artifacts, false);
       
   913   if (leakp_writer == NULL) {
       
   914     CldWriterWithUnTag cldwut(&cldw, &untag);
       
   915     KlassCldWriterWithUnTag kcldwut(&cldwut);
       
   916     _artifacts->iterate_klasses(kcldwut);
       
   917     CldWriterWithClear cldwwc(&cldw, &clear);
       
   918     CldCallback callback(&cldwwc);
       
   919     _subsystem_callback = &callback;
       
   920     do_class_loaders();
       
   921     return;
       
   922   }
       
   923   LeakCldWriter lcldw(leakp_writer, _artifacts, false);
       
   924   CompositeCldWriter ccldw(&lcldw, &cldw);
       
   925   CompositeCldWriterWithUnTag cldwwut(&ccldw, &untag);
       
   926   KlassCompositeCldWriterWithUnTag kccldw(&cldwwut);
       
   927   _artifacts->iterate_klasses(kccldw);
       
   928   CompositeCldWriterWithClear ccldwwc(&ccldw, &clear);
       
   929   CompositeCldCallback callback(&ccldwwc);
       
   930   _subsystem_callback = &callback;
       
   931   do_class_loaders();
       
   932 }
       
   933 
       
   934 template <bool predicate_bool, typename MethodFunctor>
       
   935 class MethodIteratorHost {
       
   936  private:
       
   937   MethodFunctor _method_functor;
       
   938   MethodUsedPredicate<predicate_bool> _method_used_predicate;
       
   939   MethodFlagPredicate _method_flag_predicate;
       
   940 
       
   941  public:
       
   942   MethodIteratorHost(JfrCheckpointWriter* writer,
       
   943                      JfrArtifactSet* artifacts,
       
   944                      bool current_epoch,
       
   945                      bool skip_header = false) :
       
   946     _method_functor(writer, artifacts, current_epoch, skip_header),
       
   947     _method_used_predicate(current_epoch),
       
   948     _method_flag_predicate(current_epoch) {}
       
   949 
       
   950   bool operator()(KlassPtr klass) {
       
   951     if (_method_used_predicate(klass)) {
       
   952       assert(METHOD_AND_CLASS_USED_ANY_EPOCH(klass), "invariant");
       
   953       const InstanceKlass* ik = InstanceKlass::cast(klass);
       
   954       const int len = ik->methods()->length();
       
   955       for (int i = 0; i < len; ++i) {
       
   956         MethodPtr method = ik->methods()->at(i);
       
   957         if (_method_flag_predicate(method)) {
       
   958           _method_functor(method);
       
   959         }
       
   960       }
       
   961     }
       
   962     return true;
       
   963   }
       
   964 
       
   965   int count() const { return _method_functor.count(); }
       
   966   void add(int count) { _method_functor.add(count); }
       
   967 };
       
   968 
       
   969 typedef MethodIteratorHost<true /*leakp */,  LeakpMethodWriterImpl> LeakMethodWriter;
       
   970 typedef MethodIteratorHost<false, MethodWriterImpl> MethodWriter;
       
   971 typedef CompositeFunctor<KlassPtr, LeakMethodWriter, MethodWriter> CompositeMethodWriter;
       
   972 
       
   973 /*
       
   974  * Composite operation
       
   975  *
       
   976  * LeakpMethodWriter ->
       
   977  *   MethodWriter
       
   978  */
       
   979 void JfrTypeSet::write_method_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
       
   980   assert(_artifacts->has_klass_entries(), "invariant");
       
   981   MethodWriter mw(writer, _artifacts, is_not_rotating());
       
   982   if (leakp_writer == NULL) {
       
   983     _artifacts->iterate_klasses(mw);
       
   984     _artifacts->tally(mw);
       
   985     return;
       
   986   }
       
   987   LeakMethodWriter lpmw(leakp_writer, _artifacts, is_not_rotating());
       
   988   CompositeMethodWriter cmw(&lpmw, &mw);
       
   989   _artifacts->iterate_klasses(cmw);
       
   990 }
       
   991 
       
   992 static void write_symbols_leakp(JfrCheckpointWriter* leakp_writer, JfrArtifactSet* artifacts, bool current_epoch) {
       
   993   assert(leakp_writer != NULL, "invariant");
       
   994   assert(artifacts != NULL, "invariant");
       
   995   LeakKlassSymbolWriter lpksw(leakp_writer, artifacts, current_epoch);
       
   996   artifacts->iterate_klasses(lpksw);
       
   997 }
       
   998 
       
   999 static void write_symbols(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer, JfrArtifactSet* artifacts, bool current_epoch) {
       
  1000   assert(writer != NULL, "invariant");
       
  1001   assert(artifacts != NULL, "invariant");
       
  1002   if (leakp_writer != NULL) {
       
  1003     write_symbols_leakp(leakp_writer, artifacts, current_epoch);
       
  1004   }
       
  1005   // iterate all registered symbols
       
  1006   SymbolEntryWriter symbol_writer(writer, artifacts, current_epoch);
       
  1007   artifacts->iterate_symbols(symbol_writer);
       
  1008   CStringEntryWriter cstring_writer(writer, artifacts, current_epoch, true); // skip header
       
  1009   artifacts->iterate_cstrings(cstring_writer);
       
  1010   symbol_writer.add(cstring_writer.count());
       
  1011   artifacts->tally(symbol_writer);
       
  1012 }
       
  1013 
       
  1014 bool JfrTypeSet::_class_unload = false;
       
  1015 bool JfrTypeSet::_flushpoint = false;
       
  1016 JfrArtifactSet* JfrTypeSet::_artifacts = NULL;
       
  1017 JfrArtifactClosure* JfrTypeSet::_subsystem_callback = NULL;
       
  1018 
       
  1019 bool JfrTypeSet::is_rotating() {
       
  1020   return !(_class_unload || _flushpoint);
       
  1021 }
       
  1022 
       
  1023 bool JfrTypeSet::is_not_rotating() {
       
  1024   return !is_rotating();
       
  1025 }
       
  1026 
       
  1027 bool JfrTypeSet::current_epoch() {
       
  1028   return is_not_rotating();
       
  1029 }
       
  1030 
       
  1031 void JfrTypeSet::write_symbol_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
       
  1032   assert(writer != NULL, "invariant");
       
  1033   assert(_artifacts->has_klass_entries(), "invariant");
       
  1034   write_symbols(writer, leakp_writer, _artifacts, _class_unload);
       
  1035 }
       
  1036 
       
  1037 void JfrTypeSet::do_unloaded_klass(Klass* klass) {
       
  1038   assert(klass != NULL, "invariant");
   184   assert(klass != NULL, "invariant");
  1039   assert(_subsystem_callback != NULL, "invariant");
   185   assert(_subsystem_callback != NULL, "invariant");
  1040   if (IS_JDK_JFR_EVENT_SUBKLASS(klass)) {
   186   if (IS_JDK_JFR_EVENT_SUBKLASS(klass)) {
  1041     JfrEventClasses::increment_unloaded_event_class();
   187     JfrEventClasses::increment_unloaded_event_class();
  1042   }
   188   }
  1043   if (USED_THIS_EPOCH(klass)) { // includes leakp subset
   189   if (USED_THIS_EPOCH(klass)) {
       
   190     ObjectSampleCheckpoint::on_klass_unload(klass);
  1044     _subsystem_callback->do_artifact(klass);
   191     _subsystem_callback->do_artifact(klass);
  1045     return;
   192     return;
  1046   }
   193   }
  1047   if (klass->is_subclass_of(SystemDictionary::ClassLoader_klass()) || klass == SystemDictionary::Object_klass()) {
   194   do_implied(klass);
  1048     SET_LEAKP_USED_THIS_EPOCH(klass); // tag leakp "safe byte" for subset inclusion
   195 }
  1049     _subsystem_callback->do_artifact(klass);
   196 
  1050   }
   197 static void do_klass(Klass* klass) {
  1051 }
       
  1052 
       
  1053 void JfrTypeSet::do_klass(Klass* klass) {
       
  1054   assert(klass != NULL, "invariant");
   198   assert(klass != NULL, "invariant");
  1055   assert(_subsystem_callback != NULL, "invariant");
   199   assert(_subsystem_callback != NULL, "invariant");
  1056   if (_flushpoint) {
   200   if (_flushpoint) {
  1057     if (USED_THIS_EPOCH(klass)) {
   201     if (USED_THIS_EPOCH(klass)) {
  1058       _subsystem_callback->do_artifact(klass);
   202       _subsystem_callback->do_artifact(klass);
  1059       return;
   203       return;
  1060     }
   204     }
  1061   } else {
   205   } else {
  1062     if (USED_PREV_EPOCH(klass)) { // includes leakp subset
   206     if (USED_PREV_EPOCH(klass)) {
  1063       _subsystem_callback->do_artifact(klass);
   207       _subsystem_callback->do_artifact(klass);
  1064       return;
   208       return;
  1065     }
   209     }
  1066   }
   210   }
  1067   if (klass->is_subclass_of(SystemDictionary::ClassLoader_klass()) || klass == SystemDictionary::Object_klass()) {
   211   do_implied(klass);
  1068     if (_flushpoint) {
   212 }
  1069       SET_LEAKP_USED_THIS_EPOCH(klass);
   213 
  1070     } else {
   214 static void do_klasses() {
  1071       SET_LEAKP_USED_PREV_EPOCH(klass); // tag leakp "safe byte" for subset inclusion
       
  1072     }
       
  1073     _subsystem_callback->do_artifact(klass);
       
  1074   }
       
  1075 }
       
  1076 
       
  1077 void JfrTypeSet::do_klasses() {
       
  1078   if (_class_unload) {
   215   if (_class_unload) {
  1079     ClassLoaderDataGraph::classes_unloading_do(&do_unloaded_klass);
   216     ClassLoaderDataGraph::classes_unloading_do(&do_unloaded_klass);
  1080     return;
   217     return;
  1081   }
   218   }
  1082   ClassLoaderDataGraph::classes_do(&do_klass);
   219   ClassLoaderDataGraph::classes_do(&do_klass);
  1083 }
   220 }
  1084 
   221 
  1085 template <typename T>
   222 typedef SerializePredicate<KlassPtr> KlassPredicate;
  1086 static void do_current_epoch_artifact(JfrArtifactClosure* callback, T* value) {
   223 typedef JfrPredicatedTypeWriterImplHost<KlassPtr, KlassPredicate, write__klass> KlassWriterImpl;
  1087   assert(callback != NULL, "invariant");
   224 typedef JfrTypeWriterHost<KlassWriterImpl, TYPE_CLASS> KlassWriter;
  1088   assert(value != NULL, "invariant");
   225 typedef CompositeFunctor<KlassPtr, KlassWriter, KlassArtifactRegistrator> KlassWriterRegistration;
  1089   if (ANY_USED_THIS_EPOCH(value)) { // includes leakp subset
   226 typedef JfrArtifactCallbackHost<KlassPtr, KlassWriterRegistration> KlassCallback;
  1090     callback->do_artifact(value);
   227 
  1091   }
   228 static bool write_klasses() {
       
   229   assert(!_artifacts->has_klass_entries(), "invariant");
       
   230   assert(_writer != NULL, "invariant");
       
   231   KlassArtifactRegistrator reg(_artifacts);
       
   232   KlassWriter kw(_writer, _class_unload);
       
   233   KlassWriterRegistration kwr(&kw, &reg);
       
   234   KlassCallback callback(&kwr);
       
   235   _subsystem_callback = &callback;
       
   236   do_klasses();
       
   237   if (is_complete()) {
       
   238     return false;
       
   239   }
       
   240   _artifacts->tally(kw);
       
   241   return true;
  1092 }
   242 }
  1093 
   243 
  1094 template <typename T>
   244 template <typename T>
  1095 static void do_previous_epoch_artifact(JfrArtifactClosure* callback, T* value) {
   245 static void do_previous_epoch_artifact(JfrArtifactClosure* callback, T* value) {
  1096   assert(callback != NULL, "invariant");
   246   assert(callback != NULL, "invariant");
  1097   assert(value != NULL, "invariant");
   247   assert(value != NULL, "invariant");
  1098   if (ANY_USED_PREV_EPOCH(value)) { // includes leakp subset
   248   if (USED_PREV_EPOCH(value)) {
  1099     callback->do_artifact(value);
   249     callback->do_artifact(value);
  1100     assert(IS_NOT_SERIALIZED(value), "invariant");
   250     assert(IS_NOT_SERIALIZED(value), "invariant");
  1101     return;
   251     return;
  1102   }
   252   }
  1103   if (IS_SERIALIZED(value)) {
   253   if (IS_SERIALIZED(value)) {
  1104     UNSERIALIZE(value);
   254     CLEAR_SERIALIZED(value);
  1105   }
   255   }
  1106   assert(IS_NOT_SERIALIZED(value), "invariant");
   256   assert(IS_NOT_SERIALIZED(value), "invariant");
  1107 }
   257 }
  1108 void JfrTypeSet::do_unloaded_package(PackageEntry* entry) {
   258 
  1109   do_current_epoch_artifact(_subsystem_callback, entry);
   259 int write__package(JfrCheckpointWriter* writer, const void* p) {
  1110 }
   260   assert(writer != NULL, "invariant");
  1111 
   261   assert(_artifacts != NULL, "invariant");
  1112 void JfrTypeSet::do_package(PackageEntry* entry) {
   262   assert(p != NULL, "invariant");
       
   263   PkgPtr pkg = (PkgPtr)p;
       
   264   writer->write(artifact_id(pkg));
       
   265   writer->write(mark_symbol(pkg->name()));
       
   266   writer->write(module_id(pkg));
       
   267   writer->write((bool)pkg->is_exported());
       
   268   set_serialized(pkg);
       
   269   return 1;
       
   270 }
       
   271 
       
   272 static void do_package(PackageEntry* entry) {
  1113   do_previous_epoch_artifact(_subsystem_callback, entry);
   273   do_previous_epoch_artifact(_subsystem_callback, entry);
  1114 }
   274 }
  1115 
   275 
  1116 void JfrTypeSet::do_packages() {
   276 static void do_packages() {
  1117   if (_class_unload) {
       
  1118     ClassLoaderDataGraph::packages_unloading_do(&do_unloaded_package);
       
  1119     return;
       
  1120   }
       
  1121   ClassLoaderDataGraph::packages_do(&do_package);
   277   ClassLoaderDataGraph::packages_do(&do_package);
  1122 }
   278 }
  1123 
   279 
  1124 void JfrTypeSet::do_unloaded_module(ModuleEntry* entry) {
   280 class PackageFieldSelector {
  1125   do_current_epoch_artifact(_subsystem_callback, entry);
   281  public:
  1126 }
   282   typedef PkgPtr TypePtr;
  1127 
   283   static TypePtr select(KlassPtr klass) {
  1128 void JfrTypeSet::do_module(ModuleEntry* entry) {
   284     assert(klass != NULL, "invariant");
       
   285     return ((InstanceKlass*)klass)->package();
       
   286   }
       
   287 };
       
   288 
       
   289 typedef SerializePredicate<PkgPtr> PackagePredicate;
       
   290 typedef JfrPredicatedTypeWriterImplHost<PkgPtr, PackagePredicate, write__package> PackageWriterImpl;
       
   291 typedef JfrTypeWriterHost<PackageWriterImpl, TYPE_PACKAGE> PackageWriter;
       
   292 typedef CompositeFunctor<PkgPtr, PackageWriter, ClearArtifact<PkgPtr> > PackageWriterWithClear;
       
   293 typedef KlassToFieldEnvelope<PackageFieldSelector, PackageWriter> KlassPackageWriter;
       
   294 typedef JfrArtifactCallbackHost<PkgPtr, PackageWriterWithClear> PackageCallback;
       
   295 
       
   296 static void write_packages() {
       
   297   assert(_writer != NULL, "invariant");
       
   298   PackageWriter pw(_writer, _class_unload);
       
   299   KlassPackageWriter kpw(&pw);
       
   300   _artifacts->iterate_klasses(kpw);
       
   301   if (previous_epoch()) {
       
   302     ClearArtifact<PkgPtr> clear;
       
   303     PackageWriterWithClear pwwc(&pw, &clear);
       
   304     PackageCallback callback(&pwwc);
       
   305     _subsystem_callback = &callback;
       
   306     do_packages();
       
   307   }
       
   308   _artifacts->tally(pw);
       
   309 }
       
   310 
       
   311 int write__module(JfrCheckpointWriter* writer, const void* m) {
       
   312   assert(m != NULL, "invariant");
       
   313   assert(_artifacts != NULL, "invariant");
       
   314   ModPtr mod = (ModPtr)m;
       
   315   writer->write(artifact_id(mod));
       
   316   writer->write(mark_symbol(mod->name()));
       
   317   writer->write(mark_symbol(mod->version()));
       
   318   writer->write(mark_symbol(mod->location()));
       
   319   writer->write(cld_id(mod->loader_data()));
       
   320   set_serialized(mod);
       
   321   return 1;
       
   322 }
       
   323 
       
   324 static void do_module(ModuleEntry* entry) {
  1129   do_previous_epoch_artifact(_subsystem_callback, entry);
   325   do_previous_epoch_artifact(_subsystem_callback, entry);
  1130 }
   326 }
  1131 
   327 
  1132 void JfrTypeSet::do_modules() {
   328 static void do_modules() {
  1133   if (_class_unload) {
       
  1134     ClassLoaderDataGraph::modules_unloading_do(&do_unloaded_module);
       
  1135     return;
       
  1136   }
       
  1137   ClassLoaderDataGraph::modules_do(&do_module);
   329   ClassLoaderDataGraph::modules_do(&do_module);
  1138 }
   330 }
  1139 
   331 
  1140 void JfrTypeSet::do_unloaded_class_loader_data(ClassLoaderData* cld) {
   332 class ModuleFieldSelector {
  1141   do_current_epoch_artifact(_subsystem_callback, cld);
   333  public:
  1142 }
   334   typedef ModPtr TypePtr;
  1143 
   335   static TypePtr select(KlassPtr klass) {
  1144 void JfrTypeSet::do_class_loader_data(ClassLoaderData* cld) {
   336     assert(klass != NULL, "invariant");
       
   337     PkgPtr pkg = klass->package();
       
   338     return pkg != NULL ? pkg->module() : NULL;
       
   339   }
       
   340 };
       
   341 
       
   342 typedef SerializePredicate<ModPtr> ModulePredicate;
       
   343 typedef JfrPredicatedTypeWriterImplHost<ModPtr, ModulePredicate, write__module> ModuleWriterImpl;
       
   344 typedef JfrTypeWriterHost<ModuleWriterImpl, TYPE_MODULE> ModuleWriter;
       
   345 typedef CompositeFunctor<ModPtr, ModuleWriter, ClearArtifact<ModPtr> > ModuleWriterWithClear;
       
   346 typedef JfrArtifactCallbackHost<ModPtr, ModuleWriterWithClear> ModuleCallback;
       
   347 typedef KlassToFieldEnvelope<ModuleFieldSelector, ModuleWriter> KlassModuleWriter;
       
   348 
       
   349 static void write_modules() {
       
   350   assert(_writer != NULL, "invariant");
       
   351   ModuleWriter mw(_writer, _class_unload);
       
   352   KlassModuleWriter kmw(&mw);
       
   353   _artifacts->iterate_klasses(kmw);
       
   354   if (previous_epoch()) {
       
   355     ClearArtifact<ModPtr> clear;
       
   356     ModuleWriterWithClear mwwc(&mw, &clear);
       
   357     ModuleCallback callback(&mwwc);
       
   358     _subsystem_callback = &callback;
       
   359     do_modules();
       
   360   }
       
   361   _artifacts->tally(mw);
       
   362 }
       
   363 
       
   364 int write__classloader(JfrCheckpointWriter* writer, const void* c) {
       
   365   assert(c != NULL, "invariant");
       
   366   CldPtr cld = (CldPtr)c;
       
   367   assert(!cld->is_unsafe_anonymous(), "invariant");
       
   368   // class loader type
       
   369   const Klass* class_loader_klass = cld->class_loader_klass();
       
   370   if (class_loader_klass == NULL) {
       
   371     // (primordial) boot class loader
       
   372     writer->write(artifact_id(cld)); // class loader instance id
       
   373     writer->write((traceid)0);  // class loader type id (absence of)
       
   374     writer->write(create_symbol_id(1)); // 1 maps to synthetic name -> "bootstrap"
       
   375   } else {
       
   376     writer->write(artifact_id(cld)); // class loader instance id
       
   377     writer->write(artifact_id(class_loader_klass)); // class loader type id
       
   378     writer->write(mark_symbol(cld->name())); // class loader instance name
       
   379   }
       
   380   set_serialized(cld);
       
   381   return 1;
       
   382 }
       
   383 
       
   384 static void do_class_loader_data(ClassLoaderData* cld) {
  1145   do_previous_epoch_artifact(_subsystem_callback, cld);
   385   do_previous_epoch_artifact(_subsystem_callback, cld);
  1146 }
   386 }
  1147 
   387 
       
   388 class CldFieldSelector {
       
   389  public:
       
   390   typedef CldPtr TypePtr;
       
   391   static TypePtr select(KlassPtr klass) {
       
   392     assert(klass != NULL, "invariant");
       
   393     CldPtr cld = klass->class_loader_data();
       
   394     return cld->is_unsafe_anonymous() ? NULL : cld;
       
   395   }
       
   396 };
       
   397 
  1148 class CLDCallback : public CLDClosure {
   398 class CLDCallback : public CLDClosure {
  1149  private:
       
  1150   bool _class_unload;
       
  1151  public:
   399  public:
  1152   CLDCallback(bool class_unload) : _class_unload(class_unload) {}
   400   CLDCallback() {}
  1153   void do_cld(ClassLoaderData* cld) {
   401   void do_cld(ClassLoaderData* cld) {
  1154     assert(cld != NULL, "invariant");
   402     assert(cld != NULL, "invariant");
  1155     if (cld->is_unsafe_anonymous()) {
   403     if (cld->is_unsafe_anonymous()) {
  1156       return;
   404       return;
  1157     }
   405     }
  1158     if (_class_unload) {
   406     do_class_loader_data(cld);
  1159       JfrTypeSet::do_unloaded_class_loader_data(cld);
   407   }
  1160       return;
   408 };
       
   409 
       
   410 static void do_class_loaders() {
       
   411   CLDCallback cld_cb;
       
   412   ClassLoaderDataGraph::loaded_cld_do(&cld_cb);
       
   413 }
       
   414 
       
   415 typedef SerializePredicate<CldPtr> CldPredicate;
       
   416 typedef JfrPredicatedTypeWriterImplHost<CldPtr, CldPredicate, write__classloader> CldWriterImpl;
       
   417 typedef JfrTypeWriterHost<CldWriterImpl, TYPE_CLASSLOADER> CldWriter;
       
   418 typedef CompositeFunctor<CldPtr, CldWriter, ClearArtifact<CldPtr> > CldWriterWithClear;
       
   419 typedef JfrArtifactCallbackHost<CldPtr, CldWriterWithClear> CldCallback;
       
   420 typedef KlassToFieldEnvelope<CldFieldSelector, CldWriter> KlassCldWriter;
       
   421 
       
   422 static void write_classloaders() {
       
   423   assert(_writer != NULL, "invariant");
       
   424   CldWriter cldw(_writer, _class_unload);
       
   425   KlassCldWriter kcw(&cldw);
       
   426   _artifacts->iterate_klasses(kcw);
       
   427   if (previous_epoch()) {
       
   428     ClearArtifact<CldPtr> clear;
       
   429     CldWriterWithClear cldwwc(&cldw, &clear);
       
   430     CldCallback callback(&cldwwc);
       
   431     _subsystem_callback = &callback;
       
   432     do_class_loaders();
       
   433   }
       
   434   _artifacts->tally(cldw);
       
   435 }
       
   436 
       
   437 static u1 get_visibility(MethodPtr method) {
       
   438   assert(method != NULL, "invariant");
       
   439   return const_cast<Method*>(method)->is_hidden() ? (u1)1 : (u1)0;
       
   440 }
       
   441 
       
   442 template <>
       
   443 void set_serialized<Method>(MethodPtr method) {
       
   444   assert(method != NULL, "invariant");
       
   445   SET_METHOD_SERIALIZED(method);
       
   446   assert(IS_METHOD_SERIALIZED(method), "invariant");
       
   447 }
       
   448 
       
   449 int write__method(JfrCheckpointWriter* writer, const void* m) {
       
   450   assert(writer != NULL, "invariant");
       
   451   assert(_artifacts != NULL, "invariant");
       
   452   assert(m != NULL, "invariant");
       
   453   MethodPtr method = (MethodPtr)m;
       
   454   KlassPtr klass = method->method_holder();
       
   455   assert(klass != NULL, "invariant");
       
   456   assert(METHOD_USED_ANY_EPOCH(klass), "invariant");
       
   457   writer->write(method_id(klass, method));
       
   458   writer->write(artifact_id(klass));
       
   459   writer->write(mark_symbol(method->name()));
       
   460   writer->write(mark_symbol(method->signature()));
       
   461   writer->write((u2)get_flags(method));
       
   462   writer->write(get_visibility(method));
       
   463   set_serialized(method);
       
   464   return 1;
       
   465 }
       
   466 
       
   467 template <typename MethodCallback, typename KlassCallback>
       
   468 class MethodIteratorHost {
       
   469  private:
       
   470   MethodCallback _method_cb;
       
   471   KlassCallback _klass_cb;
       
   472   MethodUsedPredicate _method_used_predicate;
       
   473   MethodFlagPredicate _method_flag_predicate;
       
   474  public:
       
   475   MethodIteratorHost(JfrCheckpointWriter* writer,
       
   476                      bool current_epoch = false,
       
   477                      bool class_unload = false,
       
   478                      bool skip_header = false) :
       
   479     _method_cb(writer, class_unload, skip_header),
       
   480     _klass_cb(writer, class_unload, skip_header),
       
   481     _method_used_predicate(current_epoch),
       
   482     _method_flag_predicate(current_epoch) {}
       
   483 
       
   484   bool operator()(KlassPtr klass) {
       
   485     if (_method_used_predicate(klass)) {
       
   486       assert(METHOD_AND_CLASS_USED_ANY_EPOCH(klass), "invariant");
       
   487       const InstanceKlass* const ik = InstanceKlass::cast(klass);
       
   488       const int len = ik->methods()->length();
       
   489       for (int i = 0; i < len; ++i) {
       
   490         MethodPtr method = ik->methods()->at(i);
       
   491         if (_method_flag_predicate(method)) {
       
   492           _method_cb(method);
       
   493         }
       
   494       }
  1161     }
   495     }
  1162     JfrTypeSet::do_class_loader_data(cld);
   496     return _klass_cb(klass);
  1163   }
   497   }
       
   498 
       
   499   int count() const { return _method_cb.count(); }
       
   500   void add(int count) { _method_cb.add(count); }
  1164 };
   501 };
  1165 
   502 
  1166 void JfrTypeSet::do_class_loaders() {
   503 template <typename T, template <typename> class Impl>
  1167   CLDCallback cld_cb(_class_unload);
   504 class Wrapper {
  1168   if (_class_unload) {
   505   Impl<T> _t;
  1169     ClassLoaderDataGraph::cld_unloading_do(&cld_cb);
   506  public:
  1170     return;
   507   Wrapper(JfrCheckpointWriter*, bool, bool) : _t() {}
  1171   }
   508   bool operator()(T const& value) {
  1172   ClassLoaderDataGraph::loaded_cld_do(&cld_cb);
   509     return _t(value);
  1173 }
   510   }
  1174 
   511 };
  1175 static void clear_artifacts(JfrArtifactSet* artifacts, bool current_epoch) {
   512 
  1176   assert(artifacts != NULL, "invariant");
   513 typedef SerializePredicate<MethodPtr> MethodPredicate;
  1177   assert(artifacts->has_klass_entries(), "invariant");
   514 typedef JfrPredicatedTypeWriterImplHost<MethodPtr, MethodPredicate, write__method> MethodWriterImplTarget;
  1178 
   515 typedef JfrTypeWriterHost<MethodWriterImplTarget, TYPE_METHOD> MethodWriterImpl;
  1179   // untag
   516 typedef Wrapper<KlassPtr, Stub> KlassCallbackStub;
  1180   ClearKlassAndMethods clear(current_epoch);
   517 typedef MethodIteratorHost<MethodWriterImpl, KlassCallbackStub> MethodWriter;
  1181   artifacts->iterate_klasses(clear);
   518 
       
   519 static void write_methods() {
       
   520   assert(_writer != NULL, "invariant");
       
   521   MethodWriter mw(_writer, current_epoch(), _class_unload);
       
   522   _artifacts->iterate_klasses(mw);
       
   523   _artifacts->tally(mw);
       
   524 }
       
   525 
       
   526 template <>
       
   527 void set_serialized<JfrSymbolId::SymbolEntry>(SymbolEntryPtr ptr) {
       
   528   assert(ptr != NULL, "invariant");
       
   529   ptr->set_serialized();
       
   530   assert(ptr->is_serialized(), "invariant");
       
   531 }
       
   532 
       
   533 template <>
       
   534 void set_serialized<JfrSymbolId::CStringEntry>(CStringEntryPtr ptr) {
       
   535   assert(ptr != NULL, "invariant");
       
   536   ptr->set_serialized();
       
   537   assert(ptr->is_serialized(), "invariant");
       
   538 }
       
   539 
       
   540 int write__symbol(JfrCheckpointWriter* writer, const void* e) {
       
   541   assert(writer != NULL, "invariant");
       
   542   assert(e != NULL, "invariant");
       
   543   ResourceMark rm;
       
   544   SymbolEntryPtr entry = (SymbolEntryPtr)e;
       
   545   writer->write(create_symbol_id(entry->id()));
       
   546   writer->write(entry->value()->as_C_string());
       
   547   set_serialized(entry);
       
   548   return 1;
       
   549 }
       
   550 
       
   551 int write__cstring(JfrCheckpointWriter* writer, const void* e) {
       
   552   assert(writer != NULL, "invariant");
       
   553   assert(e != NULL, "invariant");
       
   554   CStringEntryPtr entry = (CStringEntryPtr)e;
       
   555   writer->write(create_symbol_id(entry->id()));
       
   556   writer->write(entry->value());
       
   557   set_serialized(entry);
       
   558   return 1;
       
   559 }
       
   560 
       
   561 typedef SymbolPredicate<SymbolEntryPtr> SymPredicate;
       
   562 typedef JfrPredicatedTypeWriterImplHost<SymbolEntryPtr, SymPredicate, write__symbol> SymbolEntryWriterImpl;
       
   563 typedef JfrTypeWriterHost<SymbolEntryWriterImpl, TYPE_SYMBOL> SymbolEntryWriter;
       
   564 typedef SymbolPredicate<CStringEntryPtr> CStringPredicate;
       
   565 typedef JfrPredicatedTypeWriterImplHost<CStringEntryPtr, CStringPredicate, write__cstring> CStringEntryWriterImpl;
       
   566 typedef JfrTypeWriterHost<CStringEntryWriterImpl, TYPE_SYMBOL> CStringEntryWriter;
       
   567 
       
   568 static void write_symbols() {
       
   569   assert(_writer != NULL, "invariant");
       
   570   SymbolEntryWriter symbol_writer(_writer, _class_unload);
       
   571   _artifacts->iterate_symbols(symbol_writer);
       
   572   CStringEntryWriter cstring_writer(_writer, _class_unload, true); // skip header
       
   573   _artifacts->iterate_cstrings(cstring_writer);
       
   574   symbol_writer.add(cstring_writer.count());
       
   575   _artifacts->tally(symbol_writer);
       
   576 }
       
   577 
       
   578 typedef Wrapper<KlassPtr, ClearArtifact> ClearKlassBits;
       
   579 typedef Wrapper<MethodPtr, ClearArtifact> ClearMethodFlag;
       
   580 typedef MethodIteratorHost<ClearMethodFlag, ClearKlassBits> ClearKlassAndMethods;
       
   581 
       
   582 static size_t teardown() {
       
   583   assert(_artifacts != NULL, "invariant");
       
   584   const size_t total_count = _artifacts->total_count();
       
   585   if (previous_epoch()) {
       
   586     assert(_writer != NULL, "invariant");
       
   587     ClearKlassAndMethods clear(_writer);
       
   588     _artifacts->iterate_klasses(clear);
       
   589     _artifacts->clear();
       
   590     ++checkpoint_id;
       
   591   }
       
   592   return total_count;
       
   593 }
       
   594 
       
   595 static void setup(JfrCheckpointWriter* writer, bool class_unload, bool flushpoint) {
       
   596   _writer = writer;
       
   597   _class_unload = class_unload;
       
   598   _flushpoint = flushpoint;
       
   599   if (_artifacts == NULL) {
       
   600     _artifacts = new JfrArtifactSet(class_unload);
       
   601   } else {
       
   602     _artifacts->initialize(class_unload);
       
   603   }
       
   604   assert(_artifacts != NULL, "invariant");
       
   605   assert(!_artifacts->has_klass_entries(), "invariant");
  1182 }
   606 }
  1183 
   607 
  1184 /**
   608 /**
  1185  * Write all "tagged" (in-use) constant artifacts and their dependencies.
   609  * Write all "tagged" (in-use) constant artifacts and their dependencies.
  1186  */
   610  */
  1187 size_t JfrTypeSet::serialize(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer, bool class_unload, bool flushpoint) {
   611 size_t JfrTypeSet::serialize(JfrCheckpointWriter* writer, bool class_unload, bool flushpoint) {
  1188   assert(writer != NULL, "invariant");
   612   assert(writer != NULL, "invariant");
  1189   ResourceMark rm;
   613   ResourceMark rm;
  1190   // initialization begin
   614   setup(writer, class_unload, flushpoint);
  1191   _class_unload = class_unload;
       
  1192   _flushpoint = flushpoint;
       
  1193   ++checkpoint_id;
       
  1194   if (_artifacts == NULL) {
       
  1195     _artifacts = new JfrArtifactSet(current_epoch());
       
  1196   } else {
       
  1197     _artifacts->initialize(current_epoch());
       
  1198   }
       
  1199   assert(_artifacts != NULL, "invariant");
       
  1200   assert(!_artifacts->has_klass_entries(), "invariant");
       
  1201   // initialization complete
       
  1202 
       
  1203   // write order is important because an individual write step
   615   // write order is important because an individual write step
  1204   // might tag an artifact to be written in a subsequent step
   616   // might tag an artifact to be written in a subsequent step
  1205   write_klass_constants(writer, leakp_writer);
   617   if (!write_klasses()) {
  1206   if (!_artifacts->has_klass_entries()) {
       
  1207     return 0;
   618     return 0;
  1208   }
   619   }
  1209   write_package_constants(writer, leakp_writer);
   620   write_packages();
  1210   write_module_constants(writer, leakp_writer);
   621   write_modules();
  1211   write_class_loader_constants(writer, leakp_writer);
   622   write_classloaders();
  1212   write_method_constants(writer, leakp_writer);
   623   write_methods();
  1213   write_symbol_constants(writer, leakp_writer);
   624   write_symbols();
  1214   const size_t total_count = _artifacts->total_count();
   625   return teardown();
  1215   if (!flushpoint) {
   626 }
  1216     clear_artifacts(_artifacts, class_unload);
       
  1217   }
       
  1218   return total_count;
       
  1219 }