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

Mon, 12 Aug 2019 18:30:40 +0300

author
apetushkov
date
Mon, 12 Aug 2019 18:30:40 +0300
changeset 9858
b985cbb00e68
child 9926
d20a5f399218
child 9941
45c8de52649c
permissions
-rw-r--r--

8223147: JFR Backport
8199712: Flight Recorder
8203346: JFR: Inconsistent signature of jfr_add_string_constant
8195817: JFR.stop should require name of recording
8195818: JFR.start should increase autogenerated name by one
8195819: Remove recording=x from jcmd JFR.check output
8203921: JFR thread sampling is missing fixes from JDK-8194552
8203929: Limit amount of data for JFR.dump
8203664: JFR start failure after AppCDS archive created with JFR StartFlightRecording
8003209: JFR events for network utilization
8207392: [PPC64] Implement JFR profiling
8202835: jfr/event/os/TestSystemProcess.java fails on missing events
Summary: Backport JFR from JDK11. Initial integration
Reviewed-by: neugens

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

mercurial