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

Mon, 15 Jun 2020 14:08:11 +0300

author
apetushkov
date
Mon, 15 Jun 2020 14:08:11 +0300
changeset 9926
d20a5f399218
parent 9858
b985cbb00e68
child 9949
fb74ae591209
permissions
-rw-r--r--

8245167: Top package in method profiling shows null in JMC
Reviewed-by: neugens
Contributed-by: asemenov@azul.com

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

mercurial