annotate src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp @ 53554:74109912c738

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