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

Mon, 29 Jun 2020 21:30:26 +0100

author
andrew
date
Mon, 29 Jun 2020 21:30:26 +0100
changeset 9949
fb74ae591209
parent 9941
45c8de52649c
parent 9926
d20a5f399218
permissions
-rw-r--r--

Merge

apetushkov@9858 1 /*
apetushkov@9858 2 * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
apetushkov@9858 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
apetushkov@9858 4 *
apetushkov@9858 5 * This code is free software; you can redistribute it and/or modify it
apetushkov@9858 6 * under the terms of the GNU General Public License version 2 only, as
apetushkov@9858 7 * published by the Free Software Foundation.
apetushkov@9858 8 *
apetushkov@9858 9 * This code is distributed in the hope that it will be useful, but WITHOUT
apetushkov@9858 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
apetushkov@9858 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
apetushkov@9858 12 * version 2 for more details (a copy is included in the LICENSE file that
apetushkov@9858 13 * accompanied this code).
apetushkov@9858 14 *
apetushkov@9858 15 * You should have received a copy of the GNU General Public License version
apetushkov@9858 16 * 2 along with this work; if not, write to the Free Software Foundation,
apetushkov@9858 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
apetushkov@9858 18 *
apetushkov@9858 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
apetushkov@9858 20 * or visit www.oracle.com if you need additional information or have any
apetushkov@9858 21 * questions.
apetushkov@9858 22 *
apetushkov@9858 23 */
apetushkov@9858 24
apetushkov@9858 25 #include "precompiled.hpp"
apetushkov@9858 26 #include "classfile/classLoaderData.inline.hpp"
apetushkov@9858 27 #include "classfile/javaClasses.hpp"
apetushkov@9858 28 #include "classfile/symbolTable.hpp"
apetushkov@9858 29 #include "classfile/systemDictionary.hpp"
apetushkov@9858 30 #include "jfr/jfr.hpp"
apetushkov@9858 31 #include "jfr/jni/jfrGetAllEventClasses.hpp"
apetushkov@9858 32 #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp"
apetushkov@9858 33 #include "jfr/recorder/checkpoint/types/jfrTypeSet.hpp"
apetushkov@9858 34 #include "jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp"
apetushkov@9858 35 #include "jfr/recorder/checkpoint/types/jfrTypeSetWriter.hpp"
apetushkov@9858 36 #include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
apetushkov@9858 37 #include "jfr/recorder/storage/jfrBuffer.hpp"
apetushkov@9858 38 #include "jfr/utilities/jfrHashtable.hpp"
apetushkov@9858 39 #include "jfr/utilities/jfrTypes.hpp"
apetushkov@9858 40 #include "memory/iterator.hpp"
apetushkov@9858 41 #include "memory/resourceArea.hpp"
apetushkov@9858 42 #include "oops/instanceKlass.hpp"
apetushkov@9858 43 #include "oops/objArrayKlass.hpp"
apetushkov@9858 44 #include "oops/oop.inline.hpp"
apetushkov@9858 45 #include "memory/resourceArea.hpp"
apetushkov@9858 46 #include "utilities/accessFlags.hpp"
apetushkov@9858 47
apetushkov@9858 48 // incremented on each checkpoint
apetushkov@9858 49 static u8 checkpoint_id = 0;
apetushkov@9858 50
apetushkov@9858 51 // creates a unique id by combining a checkpoint relative symbol id (2^24)
apetushkov@9858 52 // with the current checkpoint id (2^40)
apetushkov@9858 53 #define CREATE_SYMBOL_ID(sym_id) (((u8)((checkpoint_id << 24) | sym_id)))
apetushkov@9926 54 #define CREATE_PACKAGE_ID(pkg_id) (((u8)((checkpoint_id << 24) | pkg_id)))
apetushkov@9858 55
apetushkov@9858 56 typedef const Klass* KlassPtr;
apetushkov@9858 57 typedef const ClassLoaderData* CldPtr;
apetushkov@9858 58 typedef const Method* MethodPtr;
apetushkov@9858 59 typedef const Symbol* SymbolPtr;
apetushkov@9858 60 typedef const JfrSymbolId::SymbolEntry* SymbolEntryPtr;
apetushkov@9858 61 typedef const JfrSymbolId::CStringEntry* CStringEntryPtr;
apetushkov@9858 62
apetushkov@9926 63 inline uintptr_t package_name_hash(const char *s) {
apetushkov@9926 64 uintptr_t val = 0;
apetushkov@9926 65 while (*s != 0) {
apetushkov@9926 66 val = *s++ + 31 * val;
apetushkov@9926 67 }
apetushkov@9926 68 return val;
apetushkov@9926 69 }
apetushkov@9926 70
apetushkov@9926 71 static traceid package_id(KlassPtr klass, JfrArtifactSet* artifacts) {
apetushkov@9926 72 assert(klass != NULL, "invariant");
apetushkov@9926 73 char* klass_name = klass->name()->as_C_string(); // uses ResourceMark declared in JfrTypeSet::serialize()
apetushkov@9926 74 const char* pkg_name = ClassLoader::package_from_name(klass_name, NULL);
apetushkov@9926 75 if (pkg_name == NULL) {
apetushkov@9926 76 return 0;
apetushkov@9926 77 }
apetushkov@9926 78 return CREATE_PACKAGE_ID(artifacts->markPackage(pkg_name, package_name_hash(pkg_name)));
apetushkov@9926 79 }
apetushkov@9858 80
apetushkov@9858 81 static traceid cld_id(CldPtr cld) {
apetushkov@9858 82 assert(cld != NULL, "invariant");
apetushkov@9858 83 return cld->is_anonymous() ? 0 : TRACE_ID(cld);
apetushkov@9858 84 }
apetushkov@9858 85
apetushkov@9858 86 static void tag_leakp_klass_artifacts(KlassPtr k, bool class_unload) {
apetushkov@9858 87 assert(k != NULL, "invariant");
apetushkov@9858 88 CldPtr cld = k->class_loader_data();
apetushkov@9858 89 assert(cld != NULL, "invariant");
apetushkov@9858 90 if (!cld->is_anonymous()) {
apetushkov@9858 91 tag_leakp_artifact(cld, class_unload);
apetushkov@9858 92 }
apetushkov@9858 93 }
apetushkov@9858 94
apetushkov@9858 95 class TagLeakpKlassArtifact {
apetushkov@9858 96 bool _class_unload;
apetushkov@9858 97 public:
apetushkov@9858 98 TagLeakpKlassArtifact(bool class_unload) : _class_unload(class_unload) {}
apetushkov@9858 99 bool operator()(KlassPtr klass) {
apetushkov@9858 100 if (_class_unload) {
apetushkov@9858 101 if (LEAKP_USED_THIS_EPOCH(klass)) {
apetushkov@9858 102 tag_leakp_klass_artifacts(klass, _class_unload);
apetushkov@9858 103 }
apetushkov@9858 104 } else {
apetushkov@9858 105 if (LEAKP_USED_PREV_EPOCH(klass)) {
apetushkov@9858 106 tag_leakp_klass_artifacts(klass, _class_unload);
apetushkov@9858 107 }
apetushkov@9858 108 }
apetushkov@9858 109 return true;
apetushkov@9858 110 }
apetushkov@9858 111 };
apetushkov@9858 112
apetushkov@9858 113 /*
apetushkov@9858 114 * In C++03, functions used as template parameters must have external linkage;
apetushkov@9858 115 * this restriction was removed in C++11. Change back to "static" and
apetushkov@9858 116 * rename functions when C++11 becomes available.
apetushkov@9858 117 *
apetushkov@9858 118 * The weird naming is an effort to decrease the risk of name clashes.
apetushkov@9858 119 */
apetushkov@9858 120
apetushkov@9858 121 int write__artifact__klass(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* k) {
apetushkov@9858 122 assert(writer != NULL, "invariant");
apetushkov@9858 123 assert(artifacts != NULL, "invariant");
apetushkov@9858 124 assert(k != NULL, "invariant");
apetushkov@9858 125 KlassPtr klass = (KlassPtr)k;
apetushkov@9858 126 traceid pkg_id = 0;
apetushkov@9858 127 KlassPtr theklass = klass;
apetushkov@9858 128 if (theklass->oop_is_objArray()) {
apetushkov@9858 129 const ObjArrayKlass* obj_arr_klass = ObjArrayKlass::cast((Klass*)klass);
apetushkov@9858 130 theklass = obj_arr_klass->bottom_klass();
apetushkov@9858 131 }
apetushkov@9858 132 if (theklass->oop_is_instance()) {
apetushkov@9926 133 pkg_id = package_id(theklass, artifacts);
apetushkov@9858 134 } else {
apetushkov@9858 135 assert(theklass->oop_is_typeArray(), "invariant");
apetushkov@9858 136 }
apetushkov@9858 137 const traceid symbol_id = artifacts->mark(klass);
apetushkov@9858 138 assert(symbol_id > 0, "need to have an address for symbol!");
apetushkov@9858 139 writer->write(TRACE_ID(klass));
apetushkov@9858 140 writer->write(cld_id(klass->class_loader_data()));
apetushkov@9858 141 writer->write((traceid)CREATE_SYMBOL_ID(symbol_id));
apetushkov@9858 142 writer->write(pkg_id);
apetushkov@9858 143 writer->write((s4)klass->access_flags().get_flags());
apetushkov@9858 144 return 1;
apetushkov@9858 145 }
apetushkov@9858 146
apetushkov@9858 147 typedef LeakPredicate<KlassPtr> LeakKlassPredicate;
apetushkov@9858 148 typedef JfrPredicatedArtifactWriterImplHost<KlassPtr, LeakKlassPredicate, write__artifact__klass> LeakKlassWriterImpl;
apetushkov@9858 149 typedef JfrArtifactWriterHost<LeakKlassWriterImpl, TYPE_CLASS> LeakKlassWriter;
apetushkov@9858 150 typedef JfrArtifactWriterImplHost<KlassPtr, write__artifact__klass> KlassWriterImpl;
apetushkov@9858 151 typedef JfrArtifactWriterHost<KlassWriterImpl, TYPE_CLASS> KlassWriter;
apetushkov@9858 152
apetushkov@9858 153 int write__artifact__method(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* m) {
apetushkov@9858 154 assert(writer != NULL, "invariant");
apetushkov@9858 155 assert(artifacts != NULL, "invariant");
apetushkov@9858 156 assert(m != NULL, "invariant");
apetushkov@9858 157 MethodPtr method = (MethodPtr)m;
apetushkov@9858 158 const traceid method_name_symbol_id = artifacts->mark(method->name());
apetushkov@9858 159 assert(method_name_symbol_id > 0, "invariant");
apetushkov@9858 160 const traceid method_sig_symbol_id = artifacts->mark(method->signature());
apetushkov@9858 161 assert(method_sig_symbol_id > 0, "invariant");
apetushkov@9858 162 KlassPtr klass = method->method_holder();
apetushkov@9858 163 assert(klass != NULL, "invariant");
apetushkov@9858 164 assert(METHOD_USED_ANY_EPOCH(klass), "invariant");
apetushkov@9858 165 writer->write((u8)METHOD_ID(klass, method));
apetushkov@9858 166 writer->write((u8)TRACE_ID(klass));
apetushkov@9858 167 writer->write((u8)CREATE_SYMBOL_ID(method_name_symbol_id));
apetushkov@9858 168 writer->write((u8)CREATE_SYMBOL_ID(method_sig_symbol_id));
apetushkov@9858 169 writer->write((u2)method->access_flags().get_flags());
apetushkov@9858 170 writer->write(const_cast<Method*>(method)->is_hidden() ? (u1)1 : (u1)0);
apetushkov@9858 171 return 1;
apetushkov@9858 172 }
apetushkov@9858 173
apetushkov@9858 174 typedef JfrArtifactWriterImplHost<MethodPtr, write__artifact__method> MethodWriterImplTarget;
apetushkov@9858 175 typedef JfrArtifactWriterHost<MethodWriterImplTarget, TYPE_METHOD> MethodWriterImpl;
apetushkov@9858 176
apetushkov@9926 177 int write__artifact__package(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* p) {
apetushkov@9926 178 assert(writer != NULL, "invariant");
apetushkov@9926 179 assert(artifacts != NULL, "invariant");
apetushkov@9926 180 assert(p != NULL, "invariant");
apetushkov@9858 181
apetushkov@9926 182 CStringEntryPtr entry = (CStringEntryPtr)p;
apetushkov@9926 183 const traceid package_name_symbol_id = artifacts->mark(entry->value(), package_name_hash(entry->value()));
apetushkov@9926 184 assert(package_name_symbol_id > 0, "invariant");
apetushkov@9926 185 writer->write((traceid)CREATE_PACKAGE_ID(entry->id()));
apetushkov@9926 186 writer->write((traceid)CREATE_SYMBOL_ID(package_name_symbol_id));
apetushkov@9926 187 writer->write((bool)true); // exported
apetushkov@9926 188 return 1;
apetushkov@9926 189 }
apetushkov@9858 190
apetushkov@9858 191 int write__artifact__classloader(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* c) {
apetushkov@9858 192 assert(c != NULL, "invariant");
apetushkov@9858 193 CldPtr cld = (CldPtr)c;
apetushkov@9858 194 assert(!cld->is_anonymous(), "invariant");
apetushkov@9858 195 const traceid cld_id = TRACE_ID(cld);
apetushkov@9858 196 // class loader type
apetushkov@9858 197 const Klass* class_loader_klass = cld->class_loader() != NULL ? cld->class_loader()->klass() : NULL;
apetushkov@9858 198 if (class_loader_klass == NULL) {
apetushkov@9858 199 // (primordial) boot class loader
apetushkov@9858 200 writer->write(cld_id); // class loader instance id
apetushkov@9858 201 writer->write((traceid)0); // class loader type id (absence of)
apetushkov@9858 202 writer->write((traceid)CREATE_SYMBOL_ID(1)); // 1 maps to synthetic name -> "bootstrap"
apetushkov@9858 203 } else {
apetushkov@9858 204 Symbol* symbol_name = class_loader_klass->name();
apetushkov@9858 205 const traceid symbol_name_id = symbol_name != NULL ? artifacts->mark(symbol_name) : 0;
apetushkov@9858 206 writer->write(cld_id); // class loader instance id
apetushkov@9858 207 writer->write(TRACE_ID(class_loader_klass)); // class loader type id
apetushkov@9858 208 writer->write(symbol_name_id == 0 ? (traceid)0 :
apetushkov@9858 209 (traceid)CREATE_SYMBOL_ID(symbol_name_id)); // class loader instance name
apetushkov@9858 210 }
apetushkov@9858 211 return 1;
apetushkov@9858 212 }
apetushkov@9858 213
apetushkov@9858 214 typedef LeakPredicate<CldPtr> LeakCldPredicate;
apetushkov@9858 215 int _compare_cld_ptr_(CldPtr const& lhs, CldPtr const& rhs) { return lhs > rhs ? 1 : (lhs < rhs) ? -1 : 0; }
apetushkov@9858 216 typedef UniquePredicate<CldPtr, _compare_cld_ptr_> CldPredicate;
apetushkov@9858 217 typedef JfrPredicatedArtifactWriterImplHost<CldPtr, LeakCldPredicate, write__artifact__classloader> LeakCldWriterImpl;
apetushkov@9858 218 typedef JfrPredicatedArtifactWriterImplHost<CldPtr, CldPredicate, write__artifact__classloader> CldWriterImpl;
apetushkov@9858 219 typedef JfrArtifactWriterHost<LeakCldWriterImpl, TYPE_CLASSLOADER> LeakCldWriter;
apetushkov@9858 220 typedef JfrArtifactWriterHost<CldWriterImpl, TYPE_CLASSLOADER> CldWriter;
apetushkov@9858 221
apetushkov@9858 222 typedef const JfrSymbolId::SymbolEntry* SymbolEntryPtr;
apetushkov@9858 223
apetushkov@9858 224 static int write__artifact__symbol__entry__(JfrCheckpointWriter* writer,
apetushkov@9858 225 SymbolEntryPtr entry) {
apetushkov@9858 226 assert(writer != NULL, "invariant");
apetushkov@9858 227 assert(entry != NULL, "invariant");
apetushkov@9858 228 ResourceMark rm;
apetushkov@9858 229 writer->write(CREATE_SYMBOL_ID(entry->id()));
apetushkov@9858 230 writer->write(entry->value()->as_C_string());
apetushkov@9858 231 return 1;
apetushkov@9858 232 }
apetushkov@9858 233
apetushkov@9858 234 int write__artifact__symbol__entry(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* e) {
apetushkov@9858 235 assert(e != NULL, "invariant");
apetushkov@9858 236 return write__artifact__symbol__entry__(writer, (SymbolEntryPtr)e);
apetushkov@9858 237 }
apetushkov@9858 238
apetushkov@9858 239 typedef JfrArtifactWriterImplHost<SymbolEntryPtr, write__artifact__symbol__entry> SymbolEntryWriterImpl;
apetushkov@9858 240 typedef JfrArtifactWriterHost<SymbolEntryWriterImpl, TYPE_SYMBOL> SymbolEntryWriter;
apetushkov@9858 241
apetushkov@9858 242 typedef const JfrSymbolId::CStringEntry* CStringEntryPtr;
apetushkov@9858 243
apetushkov@9858 244 static int write__artifact__cstring__entry__(JfrCheckpointWriter* writer, CStringEntryPtr entry) {
apetushkov@9858 245 assert(writer != NULL, "invariant");
apetushkov@9858 246 assert(entry != NULL, "invariant");
apetushkov@9858 247 writer->write(CREATE_SYMBOL_ID(entry->id()));
apetushkov@9858 248 writer->write(entry->value());
apetushkov@9858 249 return 1;
apetushkov@9858 250 }
apetushkov@9858 251
apetushkov@9858 252 int write__artifact__cstring__entry(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* e) {
apetushkov@9858 253 assert(e != NULL, "invariant");
apetushkov@9858 254 return write__artifact__cstring__entry__(writer, (CStringEntryPtr)e);
apetushkov@9858 255 }
apetushkov@9858 256
apetushkov@9858 257 typedef JfrArtifactWriterImplHost<CStringEntryPtr, write__artifact__cstring__entry> CStringEntryWriterImpl;
apetushkov@9858 258 typedef JfrArtifactWriterHost<CStringEntryWriterImpl, TYPE_SYMBOL> CStringEntryWriter;
apetushkov@9858 259
apetushkov@9858 260 int write__artifact__klass__symbol(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* k) {
apetushkov@9858 261 assert(writer != NULL, "invariant");
apetushkov@9858 262 assert(artifacts != NULL, "invaiant");
apetushkov@9858 263 assert(k != NULL, "invariant");
apetushkov@9858 264 const InstanceKlass* const ik = (const InstanceKlass*)k;
apetushkov@9858 265 if (ik->is_anonymous()) {
apetushkov@9858 266 CStringEntryPtr entry =
apetushkov@9858 267 artifacts->map_cstring(JfrSymbolId::anonymous_klass_name_hash_code(ik));
apetushkov@9858 268 assert(entry != NULL, "invariant");
apetushkov@9858 269 return write__artifact__cstring__entry__(writer, entry);
apetushkov@9858 270 }
apetushkov@9858 271
apetushkov@9858 272 SymbolEntryPtr entry = artifacts->map_symbol(JfrSymbolId::regular_klass_name_hash_code(ik));
apetushkov@9858 273 return write__artifact__symbol__entry__(writer, entry);
apetushkov@9858 274 }
apetushkov@9858 275
apetushkov@9858 276 int _compare_traceid_(const traceid& lhs, const traceid& rhs) {
apetushkov@9858 277 return lhs > rhs ? 1 : (lhs < rhs) ? -1 : 0;
apetushkov@9858 278 }
apetushkov@9858 279
apetushkov@9858 280 template <template <typename> class Predicate>
apetushkov@9858 281 class KlassSymbolWriterImpl {
apetushkov@9858 282 private:
apetushkov@9858 283 JfrCheckpointWriter* _writer;
apetushkov@9858 284 JfrArtifactSet* _artifacts;
apetushkov@9858 285 Predicate<KlassPtr> _predicate;
apetushkov@9858 286 MethodUsedPredicate<true> _method_used_predicate;
apetushkov@9858 287 MethodFlagPredicate _method_flag_predicate;
apetushkov@9858 288 UniquePredicate<traceid, _compare_traceid_> _unique_predicate;
apetushkov@9858 289
apetushkov@9858 290 int klass_symbols(KlassPtr klass);
apetushkov@9858 291 int class_loader_symbols(CldPtr cld);
apetushkov@9858 292 int method_symbols(KlassPtr klass);
apetushkov@9858 293
apetushkov@9858 294 public:
apetushkov@9858 295 typedef KlassPtr Type;
apetushkov@9858 296 KlassSymbolWriterImpl(JfrCheckpointWriter* writer,
apetushkov@9858 297 JfrArtifactSet* artifacts,
apetushkov@9858 298 bool class_unload) : _writer(writer),
apetushkov@9858 299 _artifacts(artifacts),
apetushkov@9858 300 _predicate(class_unload),
apetushkov@9858 301 _method_used_predicate(class_unload),
apetushkov@9858 302 _method_flag_predicate(class_unload),
apetushkov@9858 303 _unique_predicate(class_unload) {}
apetushkov@9858 304
apetushkov@9858 305 int operator()(KlassPtr klass) {
apetushkov@9858 306 assert(klass != NULL, "invariant");
apetushkov@9858 307 int count = 0;
apetushkov@9858 308 if (_predicate(klass)) {
apetushkov@9858 309 count += klass_symbols(klass);
apetushkov@9858 310 CldPtr cld = klass->class_loader_data();
apetushkov@9858 311 assert(cld != NULL, "invariant");
apetushkov@9858 312 if (!cld->is_anonymous()) {
apetushkov@9858 313 count += class_loader_symbols(cld);
apetushkov@9858 314 }
apetushkov@9858 315 if (_method_used_predicate(klass)) {
apetushkov@9858 316 count += method_symbols(klass);
apetushkov@9858 317 }
apetushkov@9858 318 }
apetushkov@9858 319 return count;
apetushkov@9858 320 }
apetushkov@9858 321 };
apetushkov@9858 322
apetushkov@9858 323 template <template <typename> class Predicate>
apetushkov@9858 324 int KlassSymbolWriterImpl<Predicate>::klass_symbols(KlassPtr klass) {
apetushkov@9858 325 assert(klass != NULL, "invariant");
apetushkov@9858 326 assert(_predicate(klass), "invariant");
apetushkov@9858 327 const InstanceKlass* const ik = (const InstanceKlass*)klass;
apetushkov@9858 328 if (ik->is_anonymous()) {
apetushkov@9858 329 CStringEntryPtr entry =
apetushkov@9858 330 this->_artifacts->map_cstring(JfrSymbolId::anonymous_klass_name_hash_code(ik));
apetushkov@9858 331 assert(entry != NULL, "invariant");
apetushkov@9858 332 return _unique_predicate(entry->id()) ? write__artifact__cstring__entry__(this->_writer, entry) : 0;
apetushkov@9858 333 }
apetushkov@9858 334 SymbolEntryPtr entry = this->_artifacts->map_symbol(ik->name());
apetushkov@9858 335 assert(entry != NULL, "invariant");
apetushkov@9858 336 return _unique_predicate(entry->id()) ? write__artifact__symbol__entry__(this->_writer, entry) : 0;
apetushkov@9858 337 }
apetushkov@9858 338
apetushkov@9858 339 template <template <typename> class Predicate>
apetushkov@9858 340 int KlassSymbolWriterImpl<Predicate>::class_loader_symbols(CldPtr cld) {
apetushkov@9858 341 assert(cld != NULL, "invariant");
apetushkov@9858 342 assert(!cld->is_anonymous(), "invariant");
apetushkov@9858 343 int count = 0;
apetushkov@9858 344 // class loader type
apetushkov@9858 345 const Klass* class_loader_klass = cld->class_loader() != NULL ? cld->class_loader()->klass() : NULL;
apetushkov@9858 346 if (class_loader_klass == NULL) {
apetushkov@9858 347 // (primordial) boot class loader
apetushkov@9858 348 CStringEntryPtr entry = this->_artifacts->map_cstring(0);
apetushkov@9858 349 assert(entry != NULL, "invariant");
apetushkov@9858 350 assert(strncmp(entry->literal(),
apetushkov@9858 351 BOOTSTRAP_LOADER_NAME,
apetushkov@9858 352 BOOTSTRAP_LOADER_NAME_LEN) == 0, "invariant");
apetushkov@9858 353 if (_unique_predicate(entry->id())) {
apetushkov@9858 354 count += write__artifact__cstring__entry__(this->_writer, entry);
apetushkov@9858 355 }
apetushkov@9858 356 } else {
apetushkov@9858 357 const Symbol* class_loader_name = class_loader_klass->name()/* XXX TODO cld->name()*/;
apetushkov@9858 358 if (class_loader_name != NULL) {
apetushkov@9858 359 SymbolEntryPtr entry = this->_artifacts->map_symbol(class_loader_name);
apetushkov@9858 360 assert(entry != NULL, "invariant");
apetushkov@9858 361 if (_unique_predicate(entry->id())) {
apetushkov@9858 362 count += write__artifact__symbol__entry__(this->_writer, entry);
apetushkov@9858 363 }
apetushkov@9858 364 }
apetushkov@9858 365 }
apetushkov@9858 366 return count;
apetushkov@9858 367 }
apetushkov@9858 368
apetushkov@9858 369 template <template <typename> class Predicate>
apetushkov@9858 370 int KlassSymbolWriterImpl<Predicate>::method_symbols(KlassPtr klass) {
apetushkov@9858 371 assert(_predicate(klass), "invariant");
apetushkov@9858 372 assert(_method_used_predicate(klass), "invariant");
apetushkov@9858 373 assert(METHOD_AND_CLASS_USED_ANY_EPOCH(klass), "invariant");
apetushkov@9858 374 int count = 0;
apetushkov@9858 375 const InstanceKlass* const ik = InstanceKlass::cast((Klass*)klass);
apetushkov@9858 376 const int len = ik->methods()->length();
apetushkov@9858 377 for (int i = 0; i < len; ++i) {
apetushkov@9858 378 MethodPtr method = ik->methods()->at(i);
apetushkov@9858 379 if (_method_flag_predicate(method)) {
apetushkov@9858 380 SymbolEntryPtr entry = this->_artifacts->map_symbol(method->name());
apetushkov@9858 381 assert(entry != NULL, "invariant");
apetushkov@9858 382 if (_unique_predicate(entry->id())) {
apetushkov@9858 383 count += write__artifact__symbol__entry__(this->_writer, entry);
apetushkov@9858 384 }
apetushkov@9858 385 entry = this->_artifacts->map_symbol(method->signature());
apetushkov@9858 386 assert(entry != NULL, "invariant");
apetushkov@9858 387 if (_unique_predicate(entry->id())) {
apetushkov@9858 388 count += write__artifact__symbol__entry__(this->_writer, entry);
apetushkov@9858 389 }
apetushkov@9858 390 }
apetushkov@9858 391 }
apetushkov@9858 392 return count;
apetushkov@9858 393 }
apetushkov@9858 394
apetushkov@9858 395 typedef KlassSymbolWriterImpl<LeakPredicate> LeakKlassSymbolWriterImpl;
apetushkov@9858 396 typedef JfrArtifactWriterHost<LeakKlassSymbolWriterImpl, TYPE_SYMBOL> LeakKlassSymbolWriter;
apetushkov@9858 397
apetushkov@9858 398 class ClearKlassAndMethods {
apetushkov@9858 399 private:
apetushkov@9858 400 ClearArtifact<KlassPtr> _clear_klass_tag_bits;
apetushkov@9858 401 ClearArtifact<MethodPtr> _clear_method_flag;
apetushkov@9858 402 MethodUsedPredicate<false> _method_used_predicate;
apetushkov@9858 403
apetushkov@9858 404 public:
apetushkov@9858 405 ClearKlassAndMethods(bool class_unload) : _clear_klass_tag_bits(class_unload),
apetushkov@9858 406 _clear_method_flag(class_unload),
apetushkov@9858 407 _method_used_predicate(class_unload) {}
apetushkov@9858 408 bool operator()(KlassPtr klass) {
apetushkov@9858 409 if (_method_used_predicate(klass)) {
apetushkov@9858 410 const InstanceKlass* ik = InstanceKlass::cast((Klass*)klass);
apetushkov@9858 411 const int len = ik->methods()->length();
apetushkov@9858 412 for (int i = 0; i < len; ++i) {
apetushkov@9858 413 MethodPtr method = ik->methods()->at(i);
apetushkov@9858 414 _clear_method_flag(method);
apetushkov@9858 415 }
apetushkov@9858 416 }
apetushkov@9858 417 _clear_klass_tag_bits(klass);
apetushkov@9858 418 return true;
apetushkov@9858 419 }
apetushkov@9858 420 };
apetushkov@9858 421
apetushkov@9858 422 typedef CompositeFunctor<KlassPtr,
apetushkov@9858 423 TagLeakpKlassArtifact,
apetushkov@9858 424 LeakKlassWriter> LeakpKlassArtifactTagging;
apetushkov@9858 425
apetushkov@9858 426 typedef CompositeFunctor<KlassPtr,
apetushkov@9858 427 LeakpKlassArtifactTagging,
apetushkov@9858 428 KlassWriter> CompositeKlassWriter;
apetushkov@9858 429
apetushkov@9858 430 typedef CompositeFunctor<KlassPtr,
apetushkov@9858 431 CompositeKlassWriter,
apetushkov@9858 432 KlassArtifactRegistrator> CompositeKlassWriterRegistration;
apetushkov@9858 433
apetushkov@9858 434 typedef CompositeFunctor<KlassPtr,
apetushkov@9858 435 KlassWriter,
apetushkov@9858 436 KlassArtifactRegistrator> KlassWriterRegistration;
apetushkov@9858 437
apetushkov@9858 438 typedef JfrArtifactCallbackHost<KlassPtr, KlassWriterRegistration> KlassCallback;
apetushkov@9858 439 typedef JfrArtifactCallbackHost<KlassPtr, CompositeKlassWriterRegistration> CompositeKlassCallback;
apetushkov@9858 440
apetushkov@9858 441 /*
apetushkov@9858 442 * Composite operation
apetushkov@9858 443 *
apetushkov@9858 444 * TagLeakpKlassArtifact ->
apetushkov@9858 445 * LeakpPredicate ->
apetushkov@9858 446 * LeakpKlassWriter ->
apetushkov@9858 447 * KlassPredicate ->
apetushkov@9858 448 * KlassWriter ->
apetushkov@9858 449 * KlassWriterRegistration
apetushkov@9858 450 */
apetushkov@9858 451 void JfrTypeSet::write_klass_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
apetushkov@9858 452 assert(!_artifacts->has_klass_entries(), "invariant");
apetushkov@9858 453 KlassArtifactRegistrator reg(_artifacts);
apetushkov@9858 454 KlassWriter kw(writer, _artifacts, _class_unload);
apetushkov@9858 455 KlassWriterRegistration kwr(&kw, &reg);
apetushkov@9858 456 if (leakp_writer == NULL) {
apetushkov@9858 457 KlassCallback callback(&kwr);
apetushkov@9858 458 _subsystem_callback = &callback;
apetushkov@9858 459 do_klasses();
apetushkov@9858 460 return;
apetushkov@9858 461 }
apetushkov@9858 462 TagLeakpKlassArtifact tagging(_class_unload);
apetushkov@9858 463 LeakKlassWriter lkw(leakp_writer, _artifacts, _class_unload);
apetushkov@9858 464 LeakpKlassArtifactTagging lpkat(&tagging, &lkw);
apetushkov@9858 465 CompositeKlassWriter ckw(&lpkat, &kw);
apetushkov@9858 466 CompositeKlassWriterRegistration ckwr(&ckw, &reg);
apetushkov@9858 467 CompositeKlassCallback callback(&ckwr);
apetushkov@9858 468 _subsystem_callback = &callback;
apetushkov@9858 469 do_klasses();
apetushkov@9858 470 }
apetushkov@9858 471
apetushkov@9926 472 typedef JfrArtifactWriterImplHost<CStringEntryPtr, write__artifact__package> PackageEntryWriterImpl;
apetushkov@9926 473 typedef JfrArtifactWriterHost<PackageEntryWriterImpl, TYPE_PACKAGE> PackageEntryWriter;
apetushkov@9858 474
apetushkov@9926 475 void JfrTypeSet::write_package_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
apetushkov@9926 476 assert(_artifacts->has_klass_entries(), "invariant");
apetushkov@9926 477 assert(writer != NULL, "invariant");
apetushkov@9926 478 // below jdk9 there is no oop for packages, so nothing to do with leakp_writer
apetushkov@9926 479 // just write packages
apetushkov@9926 480 PackageEntryWriter pw(writer, _artifacts, _class_unload);
apetushkov@9926 481 _artifacts->iterate_packages(pw);
apetushkov@9926 482 }
apetushkov@9858 483
apetushkov@9858 484 typedef CompositeFunctor<CldPtr, CldWriter, ClearArtifact<CldPtr> > CldWriterWithClear;
apetushkov@9858 485 typedef CompositeFunctor<CldPtr, LeakCldWriter, CldWriter> CompositeCldWriter;
apetushkov@9858 486 typedef CompositeFunctor<CldPtr, CompositeCldWriter, ClearArtifact<CldPtr> > CompositeCldWriterWithClear;
apetushkov@9858 487 typedef JfrArtifactCallbackHost<CldPtr, CldWriterWithClear> CldCallback;
apetushkov@9858 488 typedef JfrArtifactCallbackHost<CldPtr, CompositeCldWriterWithClear> CompositeCldCallback;
apetushkov@9858 489
apetushkov@9858 490 class CldFieldSelector {
apetushkov@9858 491 public:
apetushkov@9858 492 typedef CldPtr TypePtr;
apetushkov@9858 493 static TypePtr select(KlassPtr klass) {
apetushkov@9858 494 assert(klass != NULL, "invariant");
apetushkov@9858 495 CldPtr cld = klass->class_loader_data();
apetushkov@9858 496 return cld->is_anonymous() ? NULL : cld;
apetushkov@9858 497 }
apetushkov@9858 498 };
apetushkov@9858 499
apetushkov@9858 500 typedef KlassToFieldEnvelope<CldFieldSelector, CldWriterWithClear> KlassCldWriterWithClear;
apetushkov@9858 501 typedef KlassToFieldEnvelope<CldFieldSelector, CompositeCldWriterWithClear> KlassCompositeCldWriterWithClear;
apetushkov@9858 502
apetushkov@9858 503 /*
apetushkov@9858 504 * Composite operation
apetushkov@9858 505 *
apetushkov@9858 506 * LeakpClassLoaderWriter ->
apetushkov@9858 507 * ClassLoaderWriter ->
apetushkov@9858 508 * ClearArtifact<ClassLoaderData>
apetushkov@9858 509 */
apetushkov@9858 510 void JfrTypeSet::write_class_loader_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
apetushkov@9858 511 assert(_artifacts->has_klass_entries(), "invariant");
apetushkov@9858 512 ClearArtifact<CldPtr> clear(_class_unload);
apetushkov@9858 513 CldWriter cldw(writer, _artifacts, _class_unload);
apetushkov@9858 514 if (leakp_writer == NULL) {
apetushkov@9858 515 CldWriterWithClear cldwwc(&cldw, &clear);
apetushkov@9858 516 KlassCldWriterWithClear kcldwwc(&cldwwc);
apetushkov@9858 517 _artifacts->iterate_klasses(kcldwwc);
apetushkov@9858 518 CldCallback callback(&cldwwc);
apetushkov@9858 519 _subsystem_callback = &callback;
apetushkov@9858 520 do_class_loaders();
apetushkov@9858 521 return;
apetushkov@9858 522 }
apetushkov@9858 523 LeakCldWriter lcldw(leakp_writer, _artifacts, _class_unload);
apetushkov@9858 524 CompositeCldWriter ccldw(&lcldw, &cldw);
apetushkov@9858 525 CompositeCldWriterWithClear ccldwwc(&ccldw, &clear);
apetushkov@9858 526 KlassCompositeCldWriterWithClear kcclwwc(&ccldwwc);
apetushkov@9858 527 _artifacts->iterate_klasses(kcclwwc);
apetushkov@9858 528 CompositeCldCallback callback(&ccldwwc);
apetushkov@9858 529 _subsystem_callback = &callback;
apetushkov@9858 530 do_class_loaders();
apetushkov@9858 531 }
apetushkov@9858 532
apetushkov@9858 533 template <bool predicate_bool, typename MethodFunctor>
apetushkov@9858 534 class MethodIteratorHost {
apetushkov@9858 535 private:
apetushkov@9858 536 MethodFunctor _method_functor;
apetushkov@9858 537 MethodUsedPredicate<predicate_bool> _method_used_predicate;
apetushkov@9858 538 MethodFlagPredicate _method_flag_predicate;
apetushkov@9858 539
apetushkov@9858 540 public:
apetushkov@9858 541 MethodIteratorHost(JfrCheckpointWriter* writer,
apetushkov@9858 542 JfrArtifactSet* artifacts,
apetushkov@9858 543 bool class_unload,
apetushkov@9858 544 bool skip_header = false) :
apetushkov@9858 545 _method_functor(writer, artifacts, class_unload, skip_header),
apetushkov@9858 546 _method_used_predicate(class_unload),
apetushkov@9858 547 _method_flag_predicate(class_unload) {}
apetushkov@9858 548
apetushkov@9858 549 bool operator()(KlassPtr klass) {
apetushkov@9858 550 if (_method_used_predicate(klass)) {
apetushkov@9858 551 assert(METHOD_AND_CLASS_USED_ANY_EPOCH(klass), "invariant");
apetushkov@9858 552 const InstanceKlass* ik = InstanceKlass::cast((Klass*)klass);
apetushkov@9858 553 const int len = ik->methods()->length();
apetushkov@9858 554 for (int i = 0; i < len; ++i) {
apetushkov@9858 555 MethodPtr method = ik->methods()->at(i);
apetushkov@9858 556 if (_method_flag_predicate(method)) {
apetushkov@9858 557 _method_functor(method);
apetushkov@9858 558 }
apetushkov@9858 559 }
apetushkov@9858 560 }
apetushkov@9858 561 return true;
apetushkov@9858 562 }
apetushkov@9858 563
apetushkov@9858 564 int count() const { return _method_functor.count(); }
apetushkov@9858 565 void add(int count) { _method_functor.add(count); }
apetushkov@9858 566 };
apetushkov@9858 567
apetushkov@9858 568 typedef MethodIteratorHost<true /*leakp */, MethodWriterImpl> LeakMethodWriter;
apetushkov@9858 569 typedef MethodIteratorHost<false, MethodWriterImpl> MethodWriter;
apetushkov@9858 570 typedef CompositeFunctor<KlassPtr, LeakMethodWriter, MethodWriter> CompositeMethodWriter;
apetushkov@9858 571
apetushkov@9858 572 /*
apetushkov@9858 573 * Composite operation
apetushkov@9858 574 *
apetushkov@9858 575 * LeakpMethodWriter ->
apetushkov@9858 576 * MethodWriter
apetushkov@9858 577 */
apetushkov@9858 578 void JfrTypeSet::write_method_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
apetushkov@9858 579 assert(_artifacts->has_klass_entries(), "invariant");
apetushkov@9858 580 MethodWriter mw(writer, _artifacts, _class_unload);
apetushkov@9858 581 if (leakp_writer == NULL) {
apetushkov@9858 582 _artifacts->iterate_klasses(mw);
apetushkov@9858 583 return;
apetushkov@9858 584 }
apetushkov@9858 585 LeakMethodWriter lpmw(leakp_writer, _artifacts, _class_unload);
apetushkov@9858 586 CompositeMethodWriter cmw(&lpmw, &mw);
apetushkov@9858 587 _artifacts->iterate_klasses(cmw);
apetushkov@9858 588 }
apetushkov@9858 589 static void write_symbols_leakp(JfrCheckpointWriter* leakp_writer, JfrArtifactSet* artifacts, bool class_unload) {
apetushkov@9858 590 assert(leakp_writer != NULL, "invariant");
apetushkov@9858 591 assert(artifacts != NULL, "invariant");
apetushkov@9858 592 LeakKlassSymbolWriter lpksw(leakp_writer, artifacts, class_unload);
apetushkov@9858 593 artifacts->iterate_klasses(lpksw);
apetushkov@9858 594 }
apetushkov@9858 595 static void write_symbols(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer, JfrArtifactSet* artifacts, bool class_unload) {
apetushkov@9858 596 assert(writer != NULL, "invariant");
apetushkov@9858 597 assert(artifacts != NULL, "invariant");
apetushkov@9858 598 if (leakp_writer != NULL) {
apetushkov@9858 599 write_symbols_leakp(leakp_writer, artifacts, class_unload);
apetushkov@9858 600 }
apetushkov@9858 601 // iterate all registered symbols
apetushkov@9858 602 SymbolEntryWriter symbol_writer(writer, artifacts, class_unload);
apetushkov@9858 603 artifacts->iterate_symbols(symbol_writer);
apetushkov@9858 604 CStringEntryWriter cstring_writer(writer, artifacts, class_unload, true); // skip header
apetushkov@9858 605 artifacts->iterate_cstrings(cstring_writer);
apetushkov@9858 606 symbol_writer.add(cstring_writer.count());
apetushkov@9858 607 }
apetushkov@9858 608
apetushkov@9858 609 bool JfrTypeSet::_class_unload = false;
apetushkov@9858 610 JfrArtifactSet* JfrTypeSet::_artifacts = NULL;
apetushkov@9858 611 JfrArtifactClosure* JfrTypeSet::_subsystem_callback = NULL;
apetushkov@9858 612
apetushkov@9858 613 void JfrTypeSet::write_symbol_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) {
apetushkov@9858 614 assert(writer != NULL, "invariant");
apetushkov@9858 615 assert(_artifacts->has_klass_entries(), "invariant");
apetushkov@9858 616 write_symbols(writer, leakp_writer, _artifacts, _class_unload);
apetushkov@9858 617 }
apetushkov@9858 618
apetushkov@9858 619 void JfrTypeSet::do_unloaded_klass(Klass* klass) {
apetushkov@9858 620 assert(klass != NULL, "invariant");
apetushkov@9858 621 assert(_subsystem_callback != NULL, "invariant");
apetushkov@9858 622 if (IS_JDK_JFR_EVENT_SUBKLASS(klass)) {
apetushkov@9858 623 JfrEventClasses::increment_unloaded_event_class();
apetushkov@9858 624 }
apetushkov@9858 625 if (USED_THIS_EPOCH(klass)) { // includes leakp subset
apetushkov@9858 626 _subsystem_callback->do_artifact(klass);
apetushkov@9858 627 return;
apetushkov@9858 628 }
apetushkov@9858 629 if (klass->is_subclass_of(SystemDictionary::ClassLoader_klass()) || klass == SystemDictionary::Object_klass()) {
apetushkov@9858 630 SET_LEAKP_USED_THIS_EPOCH(klass); // tag leakp "safe byte" for subset inclusion
apetushkov@9858 631 _subsystem_callback->do_artifact(klass);
apetushkov@9858 632 }
apetushkov@9858 633 }
apetushkov@9858 634
apetushkov@9858 635 void JfrTypeSet::do_klass(Klass* klass) {
apetushkov@9858 636 assert(klass != NULL, "invariant");
apetushkov@9858 637 assert(_subsystem_callback != NULL, "invariant");
apetushkov@9858 638 if (USED_PREV_EPOCH(klass)) { // includes leakp subset
apetushkov@9858 639 _subsystem_callback->do_artifact(klass);
apetushkov@9858 640 return;
apetushkov@9858 641 }
apetushkov@9858 642 if (klass->is_subclass_of(SystemDictionary::ClassLoader_klass()) || klass == SystemDictionary::Object_klass()) {
apetushkov@9858 643 SET_LEAKP_USED_PREV_EPOCH(klass); // tag leakp "safe byte" for subset inclusion
apetushkov@9858 644 _subsystem_callback->do_artifact(klass);
apetushkov@9858 645 }
apetushkov@9858 646 }
apetushkov@9858 647
apetushkov@9858 648 void JfrTypeSet::do_klasses() {
apetushkov@9858 649 if (_class_unload) {
apetushkov@9858 650 ClassLoaderDataGraph::classes_unloading_do(&do_unloaded_klass);
apetushkov@9858 651 return;
apetushkov@9858 652 }
apetushkov@9858 653 ClassLoaderDataGraph::classes_do(&do_klass);
apetushkov@9858 654 }
apetushkov@9858 655
apetushkov@9858 656 void JfrTypeSet::do_unloaded_class_loader_data(ClassLoaderData* cld) {
apetushkov@9858 657 assert(_subsystem_callback != NULL, "invariant");
apetushkov@9858 658 if (ANY_USED_THIS_EPOCH(cld)) { // includes leakp subset
apetushkov@9858 659 _subsystem_callback->do_artifact(cld);
apetushkov@9858 660 }
apetushkov@9858 661 }
apetushkov@9858 662
apetushkov@9858 663 void JfrTypeSet::do_class_loader_data(ClassLoaderData* cld) {
apetushkov@9858 664 assert(_subsystem_callback != NULL, "invariant");
apetushkov@9858 665 if (ANY_USED_PREV_EPOCH(cld)) { // includes leakp subset
apetushkov@9858 666 _subsystem_callback->do_artifact(cld);
apetushkov@9858 667 }
apetushkov@9858 668 }
apetushkov@9858 669
apetushkov@9858 670 class CLDCallback : public CLDClosure {
apetushkov@9858 671 private:
apetushkov@9858 672 bool _class_unload;
apetushkov@9858 673 public:
apetushkov@9858 674 CLDCallback(bool class_unload) : _class_unload(class_unload) {}
apetushkov@9858 675 void do_cld(ClassLoaderData* cld) {
apetushkov@9858 676 assert(cld != NULL, "invariant");
apetushkov@9858 677 if (cld->is_anonymous()) {
apetushkov@9858 678 return;
apetushkov@9858 679 }
apetushkov@9858 680 if (_class_unload) {
apetushkov@9858 681 JfrTypeSet::do_unloaded_class_loader_data(cld);
apetushkov@9858 682 return;
apetushkov@9858 683 }
apetushkov@9858 684 JfrTypeSet::do_class_loader_data(cld);
apetushkov@9858 685 }
apetushkov@9858 686 };
apetushkov@9858 687
apetushkov@9858 688 void JfrTypeSet::do_class_loaders() {
apetushkov@9858 689 CLDCallback cld_cb(_class_unload);
apetushkov@9858 690 if (_class_unload) {
apetushkov@9858 691 ClassLoaderDataGraph::cld_unloading_do(&cld_cb);
apetushkov@9858 692 return;
apetushkov@9858 693 }
apetushkov@9858 694 ClassLoaderDataGraph::cld_do(&cld_cb);
apetushkov@9858 695 }
apetushkov@9858 696
apetushkov@9858 697 static void clear_artifacts(JfrArtifactSet* artifacts,
apetushkov@9858 698 bool class_unload) {
apetushkov@9858 699 assert(artifacts != NULL, "invariant");
apetushkov@9858 700 assert(artifacts->has_klass_entries(), "invariant");
apetushkov@9858 701
apetushkov@9858 702 // untag
apetushkov@9858 703 ClearKlassAndMethods clear(class_unload);
apetushkov@9858 704 artifacts->iterate_klasses(clear);
apetushkov@9858 705 artifacts->clear();
apetushkov@9858 706 }
apetushkov@9858 707
apetushkov@9858 708 /**
apetushkov@9858 709 * Write all "tagged" (in-use) constant artifacts and their dependencies.
apetushkov@9858 710 */
apetushkov@9858 711 void JfrTypeSet::serialize(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer, bool class_unload) {
apetushkov@9858 712 assert(writer != NULL, "invariant");
apetushkov@9858 713 ResourceMark rm;
apetushkov@9858 714 // initialization begin
apetushkov@9858 715 _class_unload = class_unload;
apetushkov@9858 716 ++checkpoint_id;
apetushkov@9858 717 if (_artifacts == NULL) {
apetushkov@9858 718 _artifacts = new JfrArtifactSet(class_unload);
apetushkov@9858 719 _subsystem_callback = NULL;
apetushkov@9858 720 } else {
apetushkov@9858 721 _artifacts->initialize(class_unload);
apetushkov@9858 722 _subsystem_callback = NULL;
apetushkov@9858 723 }
apetushkov@9858 724 assert(_artifacts != NULL, "invariant");
apetushkov@9858 725 assert(!_artifacts->has_klass_entries(), "invariant");
apetushkov@9858 726 assert(_subsystem_callback == NULL, "invariant");
apetushkov@9858 727 // initialization complete
apetushkov@9858 728
apetushkov@9858 729 // write order is important because an individual write step
apetushkov@9858 730 // might tag an artifact to be written in a subsequent step
apetushkov@9858 731 write_klass_constants(writer, leakp_writer);
apetushkov@9858 732 if (_artifacts->has_klass_entries()) {
apetushkov@9926 733 write_package_constants(writer, leakp_writer);
apetushkov@9858 734 write_class_loader_constants(writer, leakp_writer);
apetushkov@9858 735 write_method_constants(writer, leakp_writer);
apetushkov@9858 736 write_symbol_constants(writer, leakp_writer);
apetushkov@9858 737 clear_artifacts(_artifacts, class_unload);
apetushkov@9858 738 }
apetushkov@9858 739 }

mercurial