diff -r b026a43e1809 -r 31ec3e55fa3d src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp Tue Oct 29 09:34:23 2019 +0800 +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp Tue Oct 29 11:33:25 2019 +0100 @@ -43,6 +43,7 @@ #include "oops/objArrayKlass.hpp" #include "oops/oop.inline.hpp" #include "utilities/accessFlags.hpp" +#include "utilities/bitMap.inline.hpp" typedef const Klass* KlassPtr; typedef const PackageEntry* PkgPtr; @@ -117,7 +118,7 @@ static traceid module_id(PkgPtr pkg, bool leakp) { assert(pkg != NULL, "invariant"); ModPtr module_entry = pkg->module(); - if (module_entry == NULL || !module_entry->is_named()) { + if (module_entry == NULL) { return 0; } if (leakp) { @@ -136,9 +137,7 @@ static traceid cld_id(CldPtr cld, bool leakp) { assert(cld != NULL, "invariant"); - if (cld->is_unsafe_anonymous()) { - return 0; - } + assert(!cld->is_unsafe_anonymous(), "invariant"); if (leakp) { SET_LEAKP(cld); } else { @@ -153,6 +152,17 @@ return ptr->access_flags().get_flags(); } +static bool is_unsafe_anonymous(const Klass* klass) { + assert(klass != NULL, "invariant"); + return klass->is_instance_klass() && ((const InstanceKlass*)klass)->is_unsafe_anonymous(); +} + +static ClassLoaderData* get_cld(const Klass* klass) { + assert(klass != NULL, "invariant"); + return is_unsafe_anonymous(klass) ? + InstanceKlass::cast(klass)->unsafe_anonymous_host()->class_loader_data() : klass->class_loader_data(); +} + template static void set_serialized(const T* ptr) { assert(ptr != NULL, "invariant"); @@ -184,7 +194,7 @@ assert(theklass->is_typeArray_klass(), "invariant"); } writer->write(artifact_id(klass)); - writer->write(cld_id(klass->class_loader_data(), leakp)); + writer->write(cld_id(get_cld(klass), leakp)); writer->write(mark_symbol(klass, leakp)); writer->write(pkg_id); writer->write(get_flags(klass)); @@ -538,13 +548,22 @@ do_previous_epoch_artifact(_subsystem_callback, cld); } -class CldFieldSelector { +class KlassCldFieldSelector { public: typedef CldPtr TypePtr; static TypePtr select(KlassPtr klass) { assert(klass != NULL, "invariant"); - CldPtr cld = klass->class_loader_data(); - return cld->is_unsafe_anonymous() ? NULL : cld; + return get_cld(klass); + } +}; + +class ModuleCldFieldSelector { +public: + typedef CldPtr TypePtr; + static TypePtr select(KlassPtr klass) { + assert(klass != NULL, "invariant"); + ModPtr mod = ModuleFieldSelector::select(klass); + return mod != NULL ? mod->loader_data() : NULL; } }; @@ -570,14 +589,18 @@ typedef JfrTypeWriterHost CldWriter; typedef CompositeFunctor > CldWriterWithClear; typedef JfrArtifactCallbackHost CldCallback; -typedef KlassToFieldEnvelope KlassCldWriter; +typedef KlassToFieldEnvelope KlassCldWriter; +typedef KlassToFieldEnvelope ModuleCldWriter; +typedef CompositeFunctor KlassAndModuleCldWriter; typedef LeakPredicate LeakCldPredicate; typedef JfrPredicatedTypeWriterImplHost LeakCldWriterImpl; typedef JfrTypeWriterHost LeakCldWriter; typedef CompositeFunctor CompositeCldWriter; -typedef KlassToFieldEnvelope KlassCompositeCldWriter; +typedef KlassToFieldEnvelope KlassCompositeCldWriter; +typedef KlassToFieldEnvelope ModuleCompositeCldWriter; +typedef CompositeFunctor KlassAndModuleCompositeCldWriter; typedef CompositeFunctor > CompositeCldWriterWithClear; typedef JfrArtifactCallbackHost CompositeCldCallback; @@ -585,14 +608,16 @@ assert(_writer != NULL, "invariant"); CldWriter cldw(_writer, _class_unload); KlassCldWriter kcw(&cldw); + ModuleCldWriter mcw(&cldw); + KlassAndModuleCldWriter kmcw(&kcw, &mcw); if (current_epoch()) { - _artifacts->iterate_klasses(kcw); + _artifacts->iterate_klasses(kmcw); _artifacts->tally(cldw); return; } assert(previous_epoch(), "invariant"); if (_leakp_writer == NULL) { - _artifacts->iterate_klasses(kcw); + _artifacts->iterate_klasses(kmcw); ClearArtifact clear; CldWriterWithClear cldwwc(&cldw, &clear); CldCallback callback(&cldwwc); @@ -602,7 +627,9 @@ LeakCldWriter lcldw(_leakp_writer, _class_unload); CompositeCldWriter ccldw(&lcldw, &cldw); KlassCompositeCldWriter kccldw(&ccldw); - _artifacts->iterate_klasses(kccldw); + ModuleCompositeCldWriter mccldw(&ccldw); + KlassAndModuleCompositeCldWriter kmccldw(&kccldw, &mccldw); + _artifacts->iterate_klasses(kmccldw); ClearArtifact clear; CompositeCldWriterWithClear ccldwwc(&ccldw, &clear); CompositeCldCallback callback(&ccldwwc); @@ -652,7 +679,31 @@ return write_method(writer, method, true); } -template +class BitMapFilter { + ResourceBitMap _bitmap; + public: + explicit BitMapFilter(int length = 0) : _bitmap((size_t)length) {} + bool operator()(size_t idx) { + if (_bitmap.size() == 0) { + return true; + } + if (_bitmap.at(idx)) { + return false; + } + _bitmap.set_bit(idx); + return true; + } +}; + +class AlwaysTrue { + public: + explicit AlwaysTrue(int length = 0) {} + bool operator()(size_t idx) { + return true; + } +}; + +template class MethodIteratorHost { private: MethodCallback _method_cb; @@ -671,13 +722,19 @@ bool operator()(KlassPtr klass) { if (_method_used_predicate(klass)) { - const InstanceKlass* const ik = InstanceKlass::cast(klass); + const InstanceKlass* ik = InstanceKlass::cast(klass); const int len = ik->methods()->length(); - for (int i = 0; i < len; ++i) { - MethodPtr method = ik->methods()->at(i); - if (_method_flag_predicate(method)) { - _method_cb(method); + Filter filter(ik->previous_versions() != NULL ? len : 0); + while (ik != NULL) { + for (int i = 0; i < len; ++i) { + MethodPtr method = ik->methods()->at(i); + if (_method_flag_predicate(method) && filter(i)) { + _method_cb(method); + } } + // There can be multiple versions of the same method running + // due to redefinition. Need to inspect the complete set of methods. + ik = ik->previous_versions(); } } return _klass_cb(klass); @@ -697,16 +754,23 @@ } }; +template +class EmptyStub { + public: + bool operator()(T const& value) { return true; } +}; + typedef SerializePredicate MethodPredicate; typedef JfrPredicatedTypeWriterImplHost MethodWriterImplTarget; -typedef Wrapper KlassCallbackStub; +typedef Wrapper KlassCallbackStub; typedef JfrTypeWriterHost MethodWriterImpl; -typedef MethodIteratorHost MethodWriter; +typedef MethodIteratorHost MethodWriter; typedef LeakPredicate LeakMethodPredicate; typedef JfrPredicatedTypeWriterImplHost LeakMethodWriterImplTarget; typedef JfrTypeWriterHost LeakMethodWriterImpl; -typedef MethodIteratorHost LeakMethodWriter; +typedef MethodIteratorHost LeakMethodWriter; +typedef MethodIteratorHost LeakMethodWriter; typedef CompositeFunctor CompositeMethodWriter; static void write_methods() { @@ -832,7 +896,7 @@ typedef Wrapper ClearKlassBits; typedef Wrapper ClearMethodFlag; -typedef MethodIteratorHost ClearKlassAndMethods; +typedef MethodIteratorHost ClearKlassAndMethods; static size_t teardown() { assert(_artifacts != NULL, "invariant");