src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.cpp

changeset 9858
b985cbb00e68
child 9926
d20a5f399218
child 9941
45c8de52649c
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.cpp	Mon Aug 12 18:30:40 2019 +0300
     1.3 @@ -0,0 +1,901 @@
     1.4 +/*
     1.5 + * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.23 + * or visit www.oracle.com if you need additional information or have any
    1.24 + * questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +#include "precompiled.hpp"
    1.29 +#include "classfile/classLoaderData.inline.hpp"
    1.30 +#include "classfile/javaClasses.hpp"
    1.31 +// XXX #include "classfile/packageEntry.hpp"
    1.32 +#include "classfile/symbolTable.hpp"
    1.33 +#include "classfile/systemDictionary.hpp"
    1.34 +#include "jfr/jfr.hpp"
    1.35 +#include "jfr/jni/jfrGetAllEventClasses.hpp"
    1.36 +#include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp"
    1.37 +#include "jfr/recorder/checkpoint/types/jfrTypeSet.hpp"
    1.38 +#include "jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp"
    1.39 +#include "jfr/recorder/checkpoint/types/jfrTypeSetWriter.hpp"
    1.40 +#include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
    1.41 +#include "jfr/recorder/storage/jfrBuffer.hpp"
    1.42 +#include "jfr/utilities/jfrHashtable.hpp"
    1.43 +#include "jfr/utilities/jfrTypes.hpp"
    1.44 +#include "memory/iterator.hpp"
    1.45 +#include "memory/resourceArea.hpp"
    1.46 +#include "oops/instanceKlass.hpp"
    1.47 +#include "oops/objArrayKlass.hpp"
    1.48 +#include "oops/oop.inline.hpp"
    1.49 +#include "memory/resourceArea.hpp"
    1.50 +#include "utilities/accessFlags.hpp"
    1.51 +
    1.52 +// incremented on each checkpoint
    1.53 +static u8 checkpoint_id = 0;
    1.54 +
    1.55 +// creates a unique id by combining a checkpoint relative symbol id (2^24)
    1.56 +// with the current checkpoint id (2^40)
    1.57 +#define CREATE_SYMBOL_ID(sym_id) (((u8)((checkpoint_id << 24) | sym_id)))
    1.58 +
    1.59 +typedef const Klass* KlassPtr;
    1.60 +// XXX typedef const PackageEntry* PkgPtr;
    1.61 +typedef const ClassLoaderData* CldPtr;
    1.62 +typedef const Method* MethodPtr;
    1.63 +typedef const Symbol* SymbolPtr;
    1.64 +typedef const JfrSymbolId::SymbolEntry* SymbolEntryPtr;
    1.65 +typedef const JfrSymbolId::CStringEntry* CStringEntryPtr;
    1.66 +
    1.67 +// XXX
    1.68 +// static traceid package_id(KlassPtr klass) {
    1.69 +//   assert(klass != NULL, "invariant");
    1.70 +//   PkgPtr pkg_entry = klass->package();
    1.71 +//   return pkg_entry == NULL ? 0 : TRACE_ID(pkg_entry);
    1.72 +// }
    1.73 +
    1.74 +static traceid cld_id(CldPtr cld) {
    1.75 +  assert(cld != NULL, "invariant");
    1.76 +  return cld->is_anonymous() ? 0 : TRACE_ID(cld);
    1.77 +}
    1.78 +
    1.79 +static void tag_leakp_klass_artifacts(KlassPtr k, bool class_unload) {
    1.80 +  assert(k != NULL, "invariant");
    1.81 +  // XXX
    1.82 +  // PkgPtr pkg = k->package();
    1.83 +  // if (pkg != NULL) {
    1.84 +  //   tag_leakp_artifact(pkg, class_unload);
    1.85 +  // }
    1.86 +  CldPtr cld = k->class_loader_data();
    1.87 +  assert(cld != NULL, "invariant");
    1.88 +  if (!cld->is_anonymous()) {
    1.89 +    tag_leakp_artifact(cld, class_unload);
    1.90 +  }
    1.91 +}
    1.92 +
    1.93 +class TagLeakpKlassArtifact {
    1.94 +  bool _class_unload;
    1.95 + public:
    1.96 +  TagLeakpKlassArtifact(bool class_unload) : _class_unload(class_unload) {}
    1.97 +  bool operator()(KlassPtr klass) {
    1.98 +    if (_class_unload) {
    1.99 +      if (LEAKP_USED_THIS_EPOCH(klass)) {
   1.100 +        tag_leakp_klass_artifacts(klass, _class_unload);
   1.101 +      }
   1.102 +    } else {
   1.103 +      if (LEAKP_USED_PREV_EPOCH(klass)) {
   1.104 +        tag_leakp_klass_artifacts(klass, _class_unload);
   1.105 +      }
   1.106 +    }
   1.107 +    return true;
   1.108 +  }
   1.109 +};
   1.110 +
   1.111 +/*
   1.112 + * In C++03, functions used as template parameters must have external linkage;
   1.113 + * this restriction was removed in C++11. Change back to "static" and
   1.114 + * rename functions when C++11 becomes available.
   1.115 + *
   1.116 + * The weird naming is an effort to decrease the risk of name clashes.
   1.117 + */
   1.118 +
   1.119 +int write__artifact__klass(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* k) {
   1.120 +  assert(writer != NULL, "invariant");
   1.121 +  assert(artifacts != NULL, "invariant");
   1.122 +  assert(k != NULL, "invariant");
   1.123 +  KlassPtr klass = (KlassPtr)k;
   1.124 +  traceid pkg_id = 0;
   1.125 +  KlassPtr theklass = klass;
   1.126 +  if (theklass->oop_is_objArray()) {
   1.127 +    const ObjArrayKlass* obj_arr_klass = ObjArrayKlass::cast((Klass*)klass);
   1.128 +    theklass = obj_arr_klass->bottom_klass();
   1.129 +  }
   1.130 +  if (theklass->oop_is_instance()) {
   1.131 +    pkg_id = 0; // XXX package_id(theklass);
   1.132 +  } else {
   1.133 +    assert(theklass->oop_is_typeArray(), "invariant");
   1.134 +  }
   1.135 +  const traceid symbol_id = artifacts->mark(klass);
   1.136 +  assert(symbol_id > 0, "need to have an address for symbol!");
   1.137 +  writer->write(TRACE_ID(klass));
   1.138 +  writer->write(cld_id(klass->class_loader_data()));
   1.139 +  writer->write((traceid)CREATE_SYMBOL_ID(symbol_id));
   1.140 +  writer->write(pkg_id);
   1.141 +  writer->write((s4)klass->access_flags().get_flags());
   1.142 +  return 1;
   1.143 +}
   1.144 +
   1.145 +typedef LeakPredicate<KlassPtr> LeakKlassPredicate;
   1.146 +typedef JfrPredicatedArtifactWriterImplHost<KlassPtr, LeakKlassPredicate, write__artifact__klass> LeakKlassWriterImpl;
   1.147 +typedef JfrArtifactWriterHost<LeakKlassWriterImpl, TYPE_CLASS> LeakKlassWriter;
   1.148 +typedef JfrArtifactWriterImplHost<KlassPtr, write__artifact__klass> KlassWriterImpl;
   1.149 +typedef JfrArtifactWriterHost<KlassWriterImpl, TYPE_CLASS> KlassWriter;
   1.150 +
   1.151 +int write__artifact__method(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* m) {
   1.152 +  assert(writer != NULL, "invariant");
   1.153 +  assert(artifacts != NULL, "invariant");
   1.154 +  assert(m != NULL, "invariant");
   1.155 +  MethodPtr method = (MethodPtr)m;
   1.156 +  const traceid method_name_symbol_id = artifacts->mark(method->name());
   1.157 +  assert(method_name_symbol_id > 0, "invariant");
   1.158 +  const traceid method_sig_symbol_id = artifacts->mark(method->signature());
   1.159 +  assert(method_sig_symbol_id > 0, "invariant");
   1.160 +  KlassPtr klass = method->method_holder();
   1.161 +  assert(klass != NULL, "invariant");
   1.162 +  assert(METHOD_USED_ANY_EPOCH(klass), "invariant");
   1.163 +  writer->write((u8)METHOD_ID(klass, method));
   1.164 +  writer->write((u8)TRACE_ID(klass));
   1.165 +  writer->write((u8)CREATE_SYMBOL_ID(method_name_symbol_id));
   1.166 +  writer->write((u8)CREATE_SYMBOL_ID(method_sig_symbol_id));
   1.167 +  writer->write((u2)method->access_flags().get_flags());
   1.168 +  writer->write(const_cast<Method*>(method)->is_hidden() ? (u1)1 : (u1)0);
   1.169 +  return 1;
   1.170 +}
   1.171 +
   1.172 +typedef JfrArtifactWriterImplHost<MethodPtr, write__artifact__method> MethodWriterImplTarget;
   1.173 +typedef JfrArtifactWriterHost<MethodWriterImplTarget, TYPE_METHOD> MethodWriterImpl;
   1.174 +
   1.175 +// XXX
   1.176 +// int write__artifact__package(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* p) {
   1.177 +//   assert(writer != NULL, "invariant");
   1.178 +//   assert(artifacts != NULL, "invariant");
   1.179 +//   assert(p != NULL, "invariant");
   1.180 +//   PkgPtr pkg = (PkgPtr)p;
   1.181 +//   Symbol* const pkg_name = pkg->name();
   1.182 +//   const traceid package_name_symbol_id = pkg_name != NULL ? artifacts->mark(pkg_name) : 0;
   1.183 +//   assert(package_name_symbol_id > 0, "invariant");
   1.184 +//   writer->write((traceid)TRACE_ID(pkg));
   1.185 +//   writer->write((traceid)CREATE_SYMBOL_ID(package_name_symbol_id));
   1.186 +//   writer->write((bool)pkg->is_exported());
   1.187 +//   return 1;
   1.188 +// }
   1.189 +
   1.190 +// typedef LeakPredicate<PkgPtr> LeakPackagePredicate;
   1.191 +// int _compare_pkg_ptr_(PkgPtr const& lhs, PkgPtr const& rhs) { return lhs > rhs ? 1 : (lhs < rhs) ? -1 : 0; }
   1.192 +// typedef UniquePredicate<PkgPtr, _compare_pkg_ptr_> PackagePredicate;
   1.193 +// typedef JfrPredicatedArtifactWriterImplHost<PkgPtr, LeakPackagePredicate, write__artifact__package> LeakPackageWriterImpl;
   1.194 +// typedef JfrPredicatedArtifactWriterImplHost<PkgPtr, PackagePredicate, write__artifact__package> PackageWriterImpl;
   1.195 +// typedef JfrArtifactWriterHost<LeakPackageWriterImpl, TYPE_PACKAGE> LeakPackageWriter;
   1.196 +// typedef JfrArtifactWriterHost<PackageWriterImpl, TYPE_PACKAGE> PackageWriter;
   1.197 +
   1.198 +int write__artifact__classloader(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* c) {
   1.199 +  assert(c != NULL, "invariant");
   1.200 +  CldPtr cld = (CldPtr)c;
   1.201 +  assert(!cld->is_anonymous(), "invariant");
   1.202 +  const traceid cld_id = TRACE_ID(cld);
   1.203 +  // class loader type
   1.204 +  const Klass* class_loader_klass = cld->class_loader() != NULL ? cld->class_loader()->klass() : NULL;
   1.205 +  if (class_loader_klass == NULL) {
   1.206 +    // (primordial) boot class loader
   1.207 +    writer->write(cld_id); // class loader instance id
   1.208 +    writer->write((traceid)0);  // class loader type id (absence of)
   1.209 +    writer->write((traceid)CREATE_SYMBOL_ID(1)); // 1 maps to synthetic name -> "bootstrap"
   1.210 +  } else {
   1.211 +    Symbol* symbol_name = class_loader_klass->name();
   1.212 +    const traceid symbol_name_id = symbol_name != NULL ? artifacts->mark(symbol_name) : 0;
   1.213 +    writer->write(cld_id); // class loader instance id
   1.214 +    writer->write(TRACE_ID(class_loader_klass)); // class loader type id
   1.215 +    writer->write(symbol_name_id == 0 ? (traceid)0 :
   1.216 +      (traceid)CREATE_SYMBOL_ID(symbol_name_id)); // class loader instance name
   1.217 +  }
   1.218 +  return 1;
   1.219 +}
   1.220 +
   1.221 +typedef LeakPredicate<CldPtr> LeakCldPredicate;
   1.222 +int _compare_cld_ptr_(CldPtr const& lhs, CldPtr const& rhs) { return lhs > rhs ? 1 : (lhs < rhs) ? -1 : 0; }
   1.223 +typedef UniquePredicate<CldPtr, _compare_cld_ptr_> CldPredicate;
   1.224 +typedef JfrPredicatedArtifactWriterImplHost<CldPtr, LeakCldPredicate, write__artifact__classloader> LeakCldWriterImpl;
   1.225 +typedef JfrPredicatedArtifactWriterImplHost<CldPtr, CldPredicate, write__artifact__classloader> CldWriterImpl;
   1.226 +typedef JfrArtifactWriterHost<LeakCldWriterImpl, TYPE_CLASSLOADER> LeakCldWriter;
   1.227 +typedef JfrArtifactWriterHost<CldWriterImpl, TYPE_CLASSLOADER> CldWriter;
   1.228 +
   1.229 +typedef const JfrSymbolId::SymbolEntry* SymbolEntryPtr;
   1.230 +
   1.231 +static int write__artifact__symbol__entry__(JfrCheckpointWriter* writer,
   1.232 +                                            SymbolEntryPtr entry) {
   1.233 +  assert(writer != NULL, "invariant");
   1.234 +  assert(entry != NULL, "invariant");
   1.235 +  ResourceMark rm;
   1.236 +  writer->write(CREATE_SYMBOL_ID(entry->id()));
   1.237 +  writer->write(entry->value()->as_C_string());
   1.238 +  return 1;
   1.239 +}
   1.240 +
   1.241 +int write__artifact__symbol__entry(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* e) {
   1.242 +  assert(e != NULL, "invariant");
   1.243 +  return write__artifact__symbol__entry__(writer, (SymbolEntryPtr)e);
   1.244 +}
   1.245 +
   1.246 +typedef JfrArtifactWriterImplHost<SymbolEntryPtr, write__artifact__symbol__entry> SymbolEntryWriterImpl;
   1.247 +typedef JfrArtifactWriterHost<SymbolEntryWriterImpl, TYPE_SYMBOL> SymbolEntryWriter;
   1.248 +
   1.249 +typedef const JfrSymbolId::CStringEntry* CStringEntryPtr;
   1.250 +
   1.251 +static int write__artifact__cstring__entry__(JfrCheckpointWriter* writer, CStringEntryPtr entry) {
   1.252 +  assert(writer != NULL, "invariant");
   1.253 +  assert(entry != NULL, "invariant");
   1.254 +  writer->write(CREATE_SYMBOL_ID(entry->id()));
   1.255 +  writer->write(entry->value());
   1.256 +  return 1;
   1.257 +}
   1.258 +
   1.259 +int write__artifact__cstring__entry(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* e) {
   1.260 +  assert(e != NULL, "invariant");
   1.261 +  return write__artifact__cstring__entry__(writer, (CStringEntryPtr)e);
   1.262 +}
   1.263 +
   1.264 +typedef JfrArtifactWriterImplHost<CStringEntryPtr, write__artifact__cstring__entry> CStringEntryWriterImpl;
   1.265 +typedef JfrArtifactWriterHost<CStringEntryWriterImpl, TYPE_SYMBOL> CStringEntryWriter;
   1.266 +
   1.267 +int write__artifact__klass__symbol(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* k) {
   1.268 +  assert(writer != NULL, "invariant");
   1.269 +  assert(artifacts != NULL, "invaiant");
   1.270 +  assert(k != NULL, "invariant");
   1.271 +  const InstanceKlass* const ik = (const InstanceKlass*)k;
   1.272 +  if (ik->is_anonymous()) {
   1.273 +    CStringEntryPtr entry =
   1.274 +      artifacts->map_cstring(JfrSymbolId::anonymous_klass_name_hash_code(ik));
   1.275 +    assert(entry != NULL, "invariant");
   1.276 +    return write__artifact__cstring__entry__(writer, entry);
   1.277 +  }
   1.278 +
   1.279 +  SymbolEntryPtr entry = artifacts->map_symbol(JfrSymbolId::regular_klass_name_hash_code(ik));
   1.280 +  return write__artifact__symbol__entry__(writer, entry);
   1.281 +}
   1.282 +
   1.283 +int _compare_traceid_(const traceid& lhs, const traceid& rhs) {
   1.284 +  return lhs > rhs ? 1 : (lhs < rhs) ? -1 : 0;
   1.285 +}
   1.286 +
   1.287 +template <template <typename> class Predicate>
   1.288 +class KlassSymbolWriterImpl {
   1.289 + private:
   1.290 +  JfrCheckpointWriter* _writer;
   1.291 +  JfrArtifactSet* _artifacts;
   1.292 +  Predicate<KlassPtr> _predicate;
   1.293 +  MethodUsedPredicate<true> _method_used_predicate;
   1.294 +  MethodFlagPredicate _method_flag_predicate;
   1.295 +  UniquePredicate<traceid, _compare_traceid_> _unique_predicate;
   1.296 +
   1.297 +  int klass_symbols(KlassPtr klass);
   1.298 +// XXX  int package_symbols(PkgPtr pkg);
   1.299 +  int class_loader_symbols(CldPtr cld);
   1.300 +  int method_symbols(KlassPtr klass);
   1.301 +
   1.302 + public:
   1.303 +  typedef KlassPtr Type;
   1.304 +  KlassSymbolWriterImpl(JfrCheckpointWriter* writer,
   1.305 +                        JfrArtifactSet* artifacts,
   1.306 +                        bool class_unload) : _writer(writer),
   1.307 +                                             _artifacts(artifacts),
   1.308 +                                             _predicate(class_unload),
   1.309 +                                             _method_used_predicate(class_unload),
   1.310 +                                             _method_flag_predicate(class_unload),
   1.311 +                                             _unique_predicate(class_unload) {}
   1.312 +
   1.313 +  int operator()(KlassPtr klass) {
   1.314 +    assert(klass != NULL, "invariant");
   1.315 +    int count = 0;
   1.316 +    if (_predicate(klass)) {
   1.317 +      count += klass_symbols(klass);
   1.318 +      // XXX
   1.319 +      // PkgPtr pkg = klass->package();
   1.320 +      // if (pkg != NULL) {
   1.321 +      //   count += package_symbols(pkg);
   1.322 +      // }
   1.323 +      CldPtr cld = klass->class_loader_data();
   1.324 +      assert(cld != NULL, "invariant");
   1.325 +      if (!cld->is_anonymous()) {
   1.326 +        count += class_loader_symbols(cld);
   1.327 +      }
   1.328 +      if (_method_used_predicate(klass)) {
   1.329 +        count += method_symbols(klass);
   1.330 +      }
   1.331 +    }
   1.332 +    return count;
   1.333 +  }
   1.334 +};
   1.335 +
   1.336 +template <template <typename> class Predicate>
   1.337 +int KlassSymbolWriterImpl<Predicate>::klass_symbols(KlassPtr klass) {
   1.338 +  assert(klass != NULL, "invariant");
   1.339 +  assert(_predicate(klass), "invariant");
   1.340 +  const InstanceKlass* const ik = (const InstanceKlass*)klass;
   1.341 +  if (ik->is_anonymous()) {
   1.342 +    CStringEntryPtr entry =
   1.343 +      this->_artifacts->map_cstring(JfrSymbolId::anonymous_klass_name_hash_code(ik));
   1.344 +    assert(entry != NULL, "invariant");
   1.345 +    return _unique_predicate(entry->id()) ? write__artifact__cstring__entry__(this->_writer, entry) : 0;
   1.346 +  }
   1.347 +  SymbolEntryPtr entry = this->_artifacts->map_symbol(ik->name());
   1.348 +  assert(entry != NULL, "invariant");
   1.349 +  return _unique_predicate(entry->id()) ? write__artifact__symbol__entry__(this->_writer, entry) : 0;
   1.350 +}
   1.351 +
   1.352 +// XXX
   1.353 +// template <template <typename> class Predicate>
   1.354 +// int KlassSymbolWriterImpl<Predicate>::package_symbols(PkgPtr pkg) {
   1.355 +//   assert(pkg != NULL, "invariant");
   1.356 +//   SymbolPtr pkg_name = pkg->name();
   1.357 +//   assert(pkg_name != NULL, "invariant");
   1.358 +//   SymbolEntryPtr package_symbol = this->_artifacts->map_symbol(pkg_name);
   1.359 +//   assert(package_symbol != NULL, "invariant");
   1.360 +//   return _unique_predicate(package_symbol->id()) ?
   1.361 +//     write__artifact__symbol__entry__(this->_writer, package_symbol) : 0;
   1.362 +// }
   1.363 +
   1.364 +// XXX
   1.365 +// template <template <typename> class Predicate>
   1.366 +// int KlassSymbolWriterImpl<Predicate>::module_symbols(ModPtr module) {
   1.367 +//   assert(module != NULL, "invariant");
   1.368 +//   assert(module->is_named(), "invariant");
   1.369 +//   int count = 0;
   1.370 +//   SymbolPtr sym = module->name();
   1.371 +//   SymbolEntryPtr entry = NULL;
   1.372 +//   if (sym != NULL) {
   1.373 +//     entry = this->_artifacts->map_symbol(sym);
   1.374 +//     assert(entry != NULL, "invariant");
   1.375 +//     if (_unique_predicate(entry->id())) {
   1.376 +//       count += write__artifact__symbol__entry__(this->_writer, entry);
   1.377 +//     }
   1.378 +//   }
   1.379 +//   sym = module->version();
   1.380 +//   if (sym != NULL) {
   1.381 +//     entry = this->_artifacts->map_symbol(sym);
   1.382 +//     assert(entry != NULL, "invariant");
   1.383 +//     if (_unique_predicate(entry->id())) {
   1.384 +//       count += write__artifact__symbol__entry__(this->_writer, entry);
   1.385 +//     }
   1.386 +//   }
   1.387 +//   sym = module->location();
   1.388 +//   if (sym != NULL) {
   1.389 +//     entry = this->_artifacts->map_symbol(sym);
   1.390 +//     assert(entry != NULL, "invariant");
   1.391 +//     if (_unique_predicate(entry->id())) {
   1.392 +//       count += write__artifact__symbol__entry__(this->_writer, entry);
   1.393 +//     }
   1.394 +//   }
   1.395 +//   return count;
   1.396 +// }
   1.397 +
   1.398 +template <template <typename> class Predicate>
   1.399 +int KlassSymbolWriterImpl<Predicate>::class_loader_symbols(CldPtr cld) {
   1.400 +  assert(cld != NULL, "invariant");
   1.401 +  assert(!cld->is_anonymous(), "invariant");
   1.402 +  int count = 0;
   1.403 +  // class loader type
   1.404 +  const Klass* class_loader_klass = cld->class_loader() != NULL ? cld->class_loader()->klass() : NULL;
   1.405 +  if (class_loader_klass == NULL) {
   1.406 +    // (primordial) boot class loader
   1.407 +    CStringEntryPtr entry = this->_artifacts->map_cstring(0);
   1.408 +    assert(entry != NULL, "invariant");
   1.409 +    assert(strncmp(entry->literal(),
   1.410 +      BOOTSTRAP_LOADER_NAME,
   1.411 +      BOOTSTRAP_LOADER_NAME_LEN) == 0, "invariant");
   1.412 +    if (_unique_predicate(entry->id())) {
   1.413 +      count += write__artifact__cstring__entry__(this->_writer, entry);
   1.414 +    }
   1.415 +  } else {
   1.416 +    const Symbol* class_loader_name = class_loader_klass->name()/* XXX TODO cld->name()*/;
   1.417 +    if (class_loader_name != NULL) {
   1.418 +      SymbolEntryPtr entry = this->_artifacts->map_symbol(class_loader_name);
   1.419 +      assert(entry != NULL, "invariant");
   1.420 +      if (_unique_predicate(entry->id())) {
   1.421 +        count += write__artifact__symbol__entry__(this->_writer, entry);
   1.422 +      }
   1.423 +    }
   1.424 +  }
   1.425 +  return count;
   1.426 +}
   1.427 +
   1.428 +template <template <typename> class Predicate>
   1.429 +int KlassSymbolWriterImpl<Predicate>::method_symbols(KlassPtr klass) {
   1.430 +  assert(_predicate(klass), "invariant");
   1.431 +  assert(_method_used_predicate(klass), "invariant");
   1.432 +  assert(METHOD_AND_CLASS_USED_ANY_EPOCH(klass), "invariant");
   1.433 +  int count = 0;
   1.434 +  const InstanceKlass* const ik = InstanceKlass::cast((Klass*)klass);
   1.435 +  const int len = ik->methods()->length();
   1.436 +  for (int i = 0; i < len; ++i) {
   1.437 +    MethodPtr method = ik->methods()->at(i);
   1.438 +    if (_method_flag_predicate(method)) {
   1.439 +      SymbolEntryPtr entry = this->_artifacts->map_symbol(method->name());
   1.440 +      assert(entry != NULL, "invariant");
   1.441 +      if (_unique_predicate(entry->id())) {
   1.442 +        count += write__artifact__symbol__entry__(this->_writer, entry);
   1.443 +      }
   1.444 +      entry = this->_artifacts->map_symbol(method->signature());
   1.445 +      assert(entry != NULL, "invariant");
   1.446 +      if (_unique_predicate(entry->id())) {
   1.447 +        count += write__artifact__symbol__entry__(this->_writer, entry);
   1.448 +      }
   1.449 +    }
   1.450 +  }
   1.451 +  return count;
   1.452 +}
   1.453 +
   1.454 +typedef KlassSymbolWriterImpl<LeakPredicate> LeakKlassSymbolWriterImpl;
   1.455 +typedef JfrArtifactWriterHost<LeakKlassSymbolWriterImpl, TYPE_SYMBOL> LeakKlassSymbolWriter;
   1.456 +
   1.457 +class ClearKlassAndMethods {
   1.458 + private:
   1.459 +  ClearArtifact<KlassPtr> _clear_klass_tag_bits;
   1.460 +  ClearArtifact<MethodPtr> _clear_method_flag;
   1.461 +  MethodUsedPredicate<false> _method_used_predicate;
   1.462 +
   1.463 + public:
   1.464 +  ClearKlassAndMethods(bool class_unload) : _clear_klass_tag_bits(class_unload),
   1.465 +                                            _clear_method_flag(class_unload),
   1.466 +                                            _method_used_predicate(class_unload) {}
   1.467 +  bool operator()(KlassPtr klass) {
   1.468 +    if (_method_used_predicate(klass)) {
   1.469 +      const InstanceKlass* ik = InstanceKlass::cast((Klass*)klass);
   1.470 +      const int len = ik->methods()->length();
   1.471 +      for (int i = 0; i < len; ++i) {
   1.472 +        MethodPtr method = ik->methods()->at(i);
   1.473 +        _clear_method_flag(method);
   1.474 +      }
   1.475 +    }
   1.476 +    _clear_klass_tag_bits(klass);
   1.477 +    return true;
   1.478 +  }
   1.479 +};
   1.480 +
   1.481 +typedef CompositeFunctor<KlassPtr,
   1.482 +                         TagLeakpKlassArtifact,
   1.483 +                         LeakKlassWriter> LeakpKlassArtifactTagging;
   1.484 +
   1.485 +typedef CompositeFunctor<KlassPtr,
   1.486 +                         LeakpKlassArtifactTagging,
   1.487 +                         KlassWriter> CompositeKlassWriter;
   1.488 +
   1.489 +typedef CompositeFunctor<KlassPtr,
   1.490 +                         CompositeKlassWriter,
   1.491 +                         KlassArtifactRegistrator> CompositeKlassWriterRegistration;
   1.492 +
   1.493 +typedef CompositeFunctor<KlassPtr,
   1.494 +                         KlassWriter,
   1.495 +                         KlassArtifactRegistrator> KlassWriterRegistration;
   1.496 +
   1.497 +typedef JfrArtifactCallbackHost<KlassPtr, KlassWriterRegistration> KlassCallback;
   1.498 +typedef JfrArtifactCallbackHost<KlassPtr, CompositeKlassWriterRegistration> CompositeKlassCallback;
   1.499 +
   1.500 +/*
   1.501 + * Composite operation
   1.502 + *
   1.503 + * TagLeakpKlassArtifact ->
   1.504 + *   LeakpPredicate ->
   1.505 + *     LeakpKlassWriter ->
   1.506 + *       KlassPredicate ->
   1.507 + *         KlassWriter ->
   1.508 + *           KlassWriterRegistration
   1.509 + */
   1.510 +void JfrTypeSet::write_klass_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
   1.511 +  assert(!_artifacts->has_klass_entries(), "invariant");
   1.512 +  KlassArtifactRegistrator reg(_artifacts);
   1.513 +  KlassWriter kw(writer, _artifacts, _class_unload);
   1.514 +  KlassWriterRegistration kwr(&kw, &reg);
   1.515 +  if (leakp_writer == NULL) {
   1.516 +    KlassCallback callback(&kwr);
   1.517 +    _subsystem_callback = &callback;
   1.518 +    do_klasses();
   1.519 +    return;
   1.520 +  }
   1.521 +  TagLeakpKlassArtifact tagging(_class_unload);
   1.522 +  LeakKlassWriter lkw(leakp_writer, _artifacts, _class_unload);
   1.523 +  LeakpKlassArtifactTagging lpkat(&tagging, &lkw);
   1.524 +  CompositeKlassWriter ckw(&lpkat, &kw);
   1.525 +  CompositeKlassWriterRegistration ckwr(&ckw, &reg);
   1.526 +  CompositeKlassCallback callback(&ckwr);
   1.527 +  _subsystem_callback = &callback;
   1.528 +  do_klasses();
   1.529 +}
   1.530 +
   1.531 +// XXX
   1.532 +// typedef CompositeFunctor<PkgPtr,
   1.533 +//                          PackageWriter,
   1.534 +//                          ClearArtifact<PkgPtr> > PackageWriterWithClear;
   1.535 +
   1.536 +// typedef CompositeFunctor<PkgPtr,
   1.537 +//                          LeakPackageWriter,
   1.538 +//                          PackageWriter> CompositePackageWriter;
   1.539 +
   1.540 +// typedef CompositeFunctor<PkgPtr,
   1.541 +//                          CompositePackageWriter,
   1.542 +//                          ClearArtifact<PkgPtr> > CompositePackageWriterWithClear;
   1.543 +
   1.544 +// class PackageFieldSelector {
   1.545 +//  public:
   1.546 +//   typedef PkgPtr TypePtr;
   1.547 +//   static TypePtr select(KlassPtr klass) {
   1.548 +//     assert(klass != NULL, "invariant");
   1.549 +//     return ((InstanceKlass*)klass)->package();
   1.550 +//   }
   1.551 +// };
   1.552 +
   1.553 +// typedef KlassToFieldEnvelope<PackageFieldSelector,
   1.554 +//                              PackageWriterWithClear> KlassPackageWriterWithClear;
   1.555 +
   1.556 +// typedef KlassToFieldEnvelope<PackageFieldSelector,
   1.557 +//                              CompositePackageWriterWithClear> KlassCompositePackageWriterWithClear;
   1.558 +
   1.559 +// typedef JfrArtifactCallbackHost<PkgPtr, PackageWriterWithClear> PackageCallback;
   1.560 +// typedef JfrArtifactCallbackHost<PkgPtr, CompositePackageWriterWithClear> CompositePackageCallback;
   1.561 +
   1.562 +// /*
   1.563 +//  * Composite operation
   1.564 +//  *
   1.565 +//  * LeakpPackageWriter ->
   1.566 +//  *   PackageWriter ->
   1.567 +//  *     ClearArtifact<PackageEntry>
   1.568 +//  *
   1.569 +//  */
   1.570 +// void JfrTypeSet::write_package_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
   1.571 +//   assert(_artifacts->has_klass_entries(), "invariant");
   1.572 +//   ClearArtifact<PkgPtr> clear(_class_unload);
   1.573 +//   PackageWriter pw(writer, _artifacts, _class_unload);
   1.574 +//   if (leakp_writer == NULL) {
   1.575 +//     PackageWriterWithClear pwwc(&pw, &clear);
   1.576 +//     KlassPackageWriterWithClear kpwwc(&pwwc);
   1.577 +//     _artifacts->iterate_klasses(kpwwc);
   1.578 +//     PackageCallback callback(&pwwc);
   1.579 +//     _subsystem_callback = &callback;
   1.580 +//     do_packages();
   1.581 +//     return;
   1.582 +//   }
   1.583 +//   LeakPackageWriter lpw(leakp_writer, _artifacts, _class_unload);
   1.584 +//   CompositePackageWriter cpw(&lpw, &pw);
   1.585 +//   CompositePackageWriterWithClear cpwwc(&cpw, &clear);
   1.586 +//   KlassCompositePackageWriterWithClear ckpw(&cpwwc);
   1.587 +//   _artifacts->iterate_klasses(ckpw);
   1.588 +//   CompositePackageCallback callback(&cpwwc);
   1.589 +//   _subsystem_callback = &callback;
   1.590 +//   do_packages();
   1.591 +// }
   1.592 +
   1.593 +// typedef CompositeFunctor<ModPtr,
   1.594 +//                          ModuleWriter,
   1.595 +//                          ClearArtifact<ModPtr> > ModuleWriterWithClear;
   1.596 +
   1.597 +// typedef CompositeFunctor<ModPtr,
   1.598 +//                          LeakModuleWriter,
   1.599 +//                          ModuleWriter> CompositeModuleWriter;
   1.600 +
   1.601 +// typedef CompositeFunctor<ModPtr,
   1.602 +//                          CompositeModuleWriter,
   1.603 +//                          ClearArtifact<ModPtr> > CompositeModuleWriterWithClear;
   1.604 +
   1.605 +// typedef JfrArtifactCallbackHost<ModPtr, ModuleWriterWithClear> ModuleCallback;
   1.606 +// typedef JfrArtifactCallbackHost<ModPtr, CompositeModuleWriterWithClear> CompositeModuleCallback;
   1.607 +
   1.608 +// XXX
   1.609 +// class ModuleFieldSelector {
   1.610 +//  public:
   1.611 +//   typedef ModPtr TypePtr;
   1.612 +//   static TypePtr select(KlassPtr klass) {
   1.613 +//     assert(klass != NULL, "invariant");
   1.614 +//     PkgPtr pkg = klass->package();
   1.615 +//     return pkg != NULL ? pkg->module() : NULL;
   1.616 +//   }
   1.617 +// };
   1.618 +
   1.619 +// typedef KlassToFieldEnvelope<ModuleFieldSelector,
   1.620 +//                              ModuleWriterWithClear> KlassModuleWriterWithClear;
   1.621 +
   1.622 +// typedef KlassToFieldEnvelope<ModuleFieldSelector,
   1.623 +//                              CompositeModuleWriterWithClear> KlassCompositeModuleWriterWithClear;
   1.624 +
   1.625 +typedef CompositeFunctor<CldPtr, CldWriter, ClearArtifact<CldPtr> > CldWriterWithClear;
   1.626 +typedef CompositeFunctor<CldPtr, LeakCldWriter, CldWriter> CompositeCldWriter;
   1.627 +typedef CompositeFunctor<CldPtr, CompositeCldWriter, ClearArtifact<CldPtr> > CompositeCldWriterWithClear;
   1.628 +typedef JfrArtifactCallbackHost<CldPtr, CldWriterWithClear> CldCallback;
   1.629 +typedef JfrArtifactCallbackHost<CldPtr, CompositeCldWriterWithClear> CompositeCldCallback;
   1.630 +
   1.631 +class CldFieldSelector {
   1.632 + public:
   1.633 +  typedef CldPtr TypePtr;
   1.634 +  static TypePtr select(KlassPtr klass) {
   1.635 +    assert(klass != NULL, "invariant");
   1.636 +    CldPtr cld = klass->class_loader_data();
   1.637 +    return cld->is_anonymous() ? NULL : cld;
   1.638 +  }
   1.639 +};
   1.640 +
   1.641 +typedef KlassToFieldEnvelope<CldFieldSelector, CldWriterWithClear> KlassCldWriterWithClear;
   1.642 +typedef KlassToFieldEnvelope<CldFieldSelector, CompositeCldWriterWithClear> KlassCompositeCldWriterWithClear;
   1.643 +
   1.644 +/*
   1.645 + * Composite operation
   1.646 + *
   1.647 + * LeakpClassLoaderWriter ->
   1.648 + *   ClassLoaderWriter ->
   1.649 + *     ClearArtifact<ClassLoaderData>
   1.650 + */
   1.651 +void JfrTypeSet::write_class_loader_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
   1.652 +  assert(_artifacts->has_klass_entries(), "invariant");
   1.653 +  ClearArtifact<CldPtr> clear(_class_unload);
   1.654 +  CldWriter cldw(writer, _artifacts, _class_unload);
   1.655 +  if (leakp_writer == NULL) {
   1.656 +    CldWriterWithClear cldwwc(&cldw, &clear);
   1.657 +    KlassCldWriterWithClear kcldwwc(&cldwwc);
   1.658 +    _artifacts->iterate_klasses(kcldwwc);
   1.659 +    CldCallback callback(&cldwwc);
   1.660 +    _subsystem_callback = &callback;
   1.661 +    do_class_loaders();
   1.662 +    return;
   1.663 +  }
   1.664 +  LeakCldWriter lcldw(leakp_writer, _artifacts, _class_unload);
   1.665 +  CompositeCldWriter ccldw(&lcldw, &cldw);
   1.666 +  CompositeCldWriterWithClear ccldwwc(&ccldw, &clear);
   1.667 +  KlassCompositeCldWriterWithClear kcclwwc(&ccldwwc);
   1.668 +  _artifacts->iterate_klasses(kcclwwc);
   1.669 +  CompositeCldCallback callback(&ccldwwc);
   1.670 +  _subsystem_callback = &callback;
   1.671 +  do_class_loaders();
   1.672 +}
   1.673 +
   1.674 +template <bool predicate_bool, typename MethodFunctor>
   1.675 +class MethodIteratorHost {
   1.676 + private:
   1.677 +  MethodFunctor _method_functor;
   1.678 +  MethodUsedPredicate<predicate_bool> _method_used_predicate;
   1.679 +  MethodFlagPredicate _method_flag_predicate;
   1.680 +
   1.681 + public:
   1.682 +  MethodIteratorHost(JfrCheckpointWriter* writer,
   1.683 +                     JfrArtifactSet* artifacts,
   1.684 +                     bool class_unload,
   1.685 +                     bool skip_header = false) :
   1.686 +    _method_functor(writer, artifacts, class_unload, skip_header),
   1.687 +    _method_used_predicate(class_unload),
   1.688 +    _method_flag_predicate(class_unload) {}
   1.689 +
   1.690 +  bool operator()(KlassPtr klass) {
   1.691 +    if (_method_used_predicate(klass)) {
   1.692 +      assert(METHOD_AND_CLASS_USED_ANY_EPOCH(klass), "invariant");
   1.693 +      const InstanceKlass* ik = InstanceKlass::cast((Klass*)klass);
   1.694 +      const int len = ik->methods()->length();
   1.695 +      for (int i = 0; i < len; ++i) {
   1.696 +        MethodPtr method = ik->methods()->at(i);
   1.697 +        if (_method_flag_predicate(method)) {
   1.698 +          _method_functor(method);
   1.699 +        }
   1.700 +      }
   1.701 +    }
   1.702 +    return true;
   1.703 +  }
   1.704 +
   1.705 +  int count() const { return _method_functor.count(); }
   1.706 +  void add(int count) { _method_functor.add(count); }
   1.707 +};
   1.708 +
   1.709 +typedef MethodIteratorHost<true /*leakp */,  MethodWriterImpl> LeakMethodWriter;
   1.710 +typedef MethodIteratorHost<false, MethodWriterImpl> MethodWriter;
   1.711 +typedef CompositeFunctor<KlassPtr, LeakMethodWriter, MethodWriter> CompositeMethodWriter;
   1.712 +
   1.713 +/*
   1.714 + * Composite operation
   1.715 + *
   1.716 + * LeakpMethodWriter ->
   1.717 + *   MethodWriter
   1.718 + */
   1.719 +void JfrTypeSet::write_method_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
   1.720 +  assert(_artifacts->has_klass_entries(), "invariant");
   1.721 +  MethodWriter mw(writer, _artifacts, _class_unload);
   1.722 +  if (leakp_writer == NULL) {
   1.723 +    _artifacts->iterate_klasses(mw);
   1.724 +    return;
   1.725 +  }
   1.726 +  LeakMethodWriter lpmw(leakp_writer, _artifacts, _class_unload);
   1.727 +  CompositeMethodWriter cmw(&lpmw, &mw);
   1.728 +  _artifacts->iterate_klasses(cmw);
   1.729 +}
   1.730 +static void write_symbols_leakp(JfrCheckpointWriter* leakp_writer, JfrArtifactSet* artifacts, bool class_unload) {
   1.731 +  assert(leakp_writer != NULL, "invariant");
   1.732 +  assert(artifacts != NULL, "invariant");
   1.733 +  LeakKlassSymbolWriter lpksw(leakp_writer, artifacts, class_unload);
   1.734 +  artifacts->iterate_klasses(lpksw);
   1.735 +}
   1.736 +static void write_symbols(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer, JfrArtifactSet* artifacts, bool class_unload) {
   1.737 +  assert(writer != NULL, "invariant");
   1.738 +  assert(artifacts != NULL, "invariant");
   1.739 +  if (leakp_writer != NULL) {
   1.740 +    write_symbols_leakp(leakp_writer, artifacts, class_unload);
   1.741 +  }
   1.742 +  // iterate all registered symbols
   1.743 +  SymbolEntryWriter symbol_writer(writer, artifacts, class_unload);
   1.744 +  artifacts->iterate_symbols(symbol_writer);
   1.745 +  CStringEntryWriter cstring_writer(writer, artifacts, class_unload, true); // skip header
   1.746 +  artifacts->iterate_cstrings(cstring_writer);
   1.747 +  symbol_writer.add(cstring_writer.count());
   1.748 +}
   1.749 +
   1.750 +bool JfrTypeSet::_class_unload = false;
   1.751 +JfrArtifactSet* JfrTypeSet::_artifacts = NULL;
   1.752 +JfrArtifactClosure* JfrTypeSet::_subsystem_callback = NULL;
   1.753 +
   1.754 +void JfrTypeSet::write_symbol_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
   1.755 +  assert(writer != NULL, "invariant");
   1.756 +  assert(_artifacts->has_klass_entries(), "invariant");
   1.757 +  write_symbols(writer, leakp_writer, _artifacts, _class_unload);
   1.758 +}
   1.759 +
   1.760 +void JfrTypeSet::do_unloaded_klass(Klass* klass) {
   1.761 +  assert(klass != NULL, "invariant");
   1.762 +  assert(_subsystem_callback != NULL, "invariant");
   1.763 +  if (IS_JDK_JFR_EVENT_SUBKLASS(klass)) {
   1.764 +    JfrEventClasses::increment_unloaded_event_class();
   1.765 +  }
   1.766 +  if (USED_THIS_EPOCH(klass)) { // includes leakp subset
   1.767 +    _subsystem_callback->do_artifact(klass);
   1.768 +    return;
   1.769 +  }
   1.770 +  if (klass->is_subclass_of(SystemDictionary::ClassLoader_klass()) || klass == SystemDictionary::Object_klass()) {
   1.771 +    SET_LEAKP_USED_THIS_EPOCH(klass); // tag leakp "safe byte" for subset inclusion
   1.772 +    _subsystem_callback->do_artifact(klass);
   1.773 +  }
   1.774 +}
   1.775 +
   1.776 +void JfrTypeSet::do_klass(Klass* klass) {
   1.777 +  assert(klass != NULL, "invariant");
   1.778 +  assert(_subsystem_callback != NULL, "invariant");
   1.779 +  if (USED_PREV_EPOCH(klass)) { // includes leakp subset
   1.780 +    _subsystem_callback->do_artifact(klass);
   1.781 +    return;
   1.782 +  }
   1.783 +  if (klass->is_subclass_of(SystemDictionary::ClassLoader_klass()) || klass == SystemDictionary::Object_klass()) {
   1.784 +    SET_LEAKP_USED_PREV_EPOCH(klass); // tag leakp "safe byte" for subset inclusion
   1.785 +    _subsystem_callback->do_artifact(klass);
   1.786 +  }
   1.787 +}
   1.788 +
   1.789 +void JfrTypeSet::do_klasses() {
   1.790 +  if (_class_unload) {
   1.791 +    ClassLoaderDataGraph::classes_unloading_do(&do_unloaded_klass);
   1.792 +    return;
   1.793 +  }
   1.794 +  ClassLoaderDataGraph::classes_do(&do_klass);
   1.795 +}
   1.796 +
   1.797 +// XXX
   1.798 +// void JfrTypeSet::do_unloaded_package(PackageEntry* entry) {
   1.799 +//   assert(entry != NULL, "invariant");
   1.800 +//   assert(_subsystem_callback != NULL, "invariant");
   1.801 +//   if (ANY_USED_THIS_EPOCH(entry)) { // includes leakp subset
   1.802 +//     _subsystem_callback->do_artifact(entry);
   1.803 +//   }
   1.804 +// }
   1.805 +
   1.806 +// void JfrTypeSet::do_package(PackageEntry* entry) {
   1.807 +//   assert(_subsystem_callback != NULL, "invariant");
   1.808 +//   if (ANY_USED_PREV_EPOCH(entry)) { // includes leakp subset
   1.809 +//     _subsystem_callback->do_artifact(entry);
   1.810 +//   }
   1.811 +// }
   1.812 +
   1.813 +// void JfrTypeSet::do_packages() {
   1.814 +//   if (_class_unload) {
   1.815 +//     ClassLoaderDataGraph::packages_unloading_do(&do_unloaded_package);
   1.816 +//     return;
   1.817 +//   }
   1.818 +//   ClassLoaderDataGraph::packages_do(&do_package);
   1.819 +// }
   1.820 +
   1.821 +void JfrTypeSet::do_unloaded_class_loader_data(ClassLoaderData* cld) {
   1.822 +  assert(_subsystem_callback != NULL, "invariant");
   1.823 +  if (ANY_USED_THIS_EPOCH(cld)) { // includes leakp subset
   1.824 +    _subsystem_callback->do_artifact(cld);
   1.825 +  }
   1.826 +}
   1.827 +
   1.828 +void JfrTypeSet::do_class_loader_data(ClassLoaderData* cld) {
   1.829 +  assert(_subsystem_callback != NULL, "invariant");
   1.830 +  if (ANY_USED_PREV_EPOCH(cld)) { // includes leakp subset
   1.831 +    _subsystem_callback->do_artifact(cld);
   1.832 +  }
   1.833 +}
   1.834 +
   1.835 +class CLDCallback : public CLDClosure {
   1.836 + private:
   1.837 +  bool _class_unload;
   1.838 + public:
   1.839 +  CLDCallback(bool class_unload) : _class_unload(class_unload) {}
   1.840 +  void do_cld(ClassLoaderData* cld) {
   1.841 +     assert(cld != NULL, "invariant");
   1.842 +    if (cld->is_anonymous()) {
   1.843 +      return;
   1.844 +    }
   1.845 +    if (_class_unload) {
   1.846 +      JfrTypeSet::do_unloaded_class_loader_data(cld);
   1.847 +      return;
   1.848 +    }
   1.849 +    JfrTypeSet::do_class_loader_data(cld);
   1.850 +  }
   1.851 +};
   1.852 +
   1.853 +void JfrTypeSet::do_class_loaders() {
   1.854 +  CLDCallback cld_cb(_class_unload);
   1.855 +  if (_class_unload) {
   1.856 +    ClassLoaderDataGraph::cld_unloading_do(&cld_cb);
   1.857 +    return;
   1.858 +  }
   1.859 +  ClassLoaderDataGraph::cld_do(&cld_cb);
   1.860 +}
   1.861 +
   1.862 +static void clear_artifacts(JfrArtifactSet* artifacts,
   1.863 +                            bool class_unload) {
   1.864 +  assert(artifacts != NULL, "invariant");
   1.865 +  assert(artifacts->has_klass_entries(), "invariant");
   1.866 +
   1.867 +  // untag
   1.868 +  ClearKlassAndMethods clear(class_unload);
   1.869 +  artifacts->iterate_klasses(clear);
   1.870 +  artifacts->clear();
   1.871 +}
   1.872 +
   1.873 +/**
   1.874 + * Write all "tagged" (in-use) constant artifacts and their dependencies.
   1.875 + */
   1.876 +void JfrTypeSet::serialize(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer, bool class_unload) {
   1.877 +  assert(writer != NULL, "invariant");
   1.878 +  ResourceMark rm;
   1.879 +  // initialization begin
   1.880 +  _class_unload = class_unload;
   1.881 +  ++checkpoint_id;
   1.882 +  if (_artifacts == NULL) {
   1.883 +    _artifacts = new JfrArtifactSet(class_unload);
   1.884 +    _subsystem_callback = NULL;
   1.885 +  } else {
   1.886 +    _artifacts->initialize(class_unload);
   1.887 +    _subsystem_callback = NULL;
   1.888 +  }
   1.889 +  assert(_artifacts != NULL, "invariant");
   1.890 +  assert(!_artifacts->has_klass_entries(), "invariant");
   1.891 +  assert(_subsystem_callback == NULL, "invariant");
   1.892 +  // initialization complete
   1.893 +
   1.894 +  // write order is important because an individual write step
   1.895 +  // might tag an artifact to be written in a subsequent step
   1.896 +  write_klass_constants(writer, leakp_writer);
   1.897 +  if (_artifacts->has_klass_entries()) {
   1.898 +// XXX    write_package_constants(writer, leakp_writer);
   1.899 +    write_class_loader_constants(writer, leakp_writer);
   1.900 +    write_method_constants(writer, leakp_writer);
   1.901 +    write_symbol_constants(writer, leakp_writer);
   1.902 +    clear_artifacts(_artifacts, class_unload);
   1.903 +  }
   1.904 +}

mercurial