src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp
changeset 58836 31ec3e55fa3d
parent 58786 7909763ad193
child 58837 2bfbb50dd97d
child 58863 c16ac7a2eba4
equal deleted inserted replaced
58831:b026a43e1809 58836:31ec3e55fa3d
    41 #include "memory/resourceArea.hpp"
    41 #include "memory/resourceArea.hpp"
    42 #include "oops/instanceKlass.hpp"
    42 #include "oops/instanceKlass.hpp"
    43 #include "oops/objArrayKlass.hpp"
    43 #include "oops/objArrayKlass.hpp"
    44 #include "oops/oop.inline.hpp"
    44 #include "oops/oop.inline.hpp"
    45 #include "utilities/accessFlags.hpp"
    45 #include "utilities/accessFlags.hpp"
       
    46 #include "utilities/bitMap.inline.hpp"
    46 
    47 
    47 typedef const Klass* KlassPtr;
    48 typedef const Klass* KlassPtr;
    48 typedef const PackageEntry* PkgPtr;
    49 typedef const PackageEntry* PkgPtr;
    49 typedef const ModuleEntry* ModPtr;
    50 typedef const ModuleEntry* ModPtr;
    50 typedef const ClassLoaderData* CldPtr;
    51 typedef const ClassLoaderData* CldPtr;
   115 }
   116 }
   116 
   117 
   117 static traceid module_id(PkgPtr pkg, bool leakp) {
   118 static traceid module_id(PkgPtr pkg, bool leakp) {
   118   assert(pkg != NULL, "invariant");
   119   assert(pkg != NULL, "invariant");
   119   ModPtr module_entry = pkg->module();
   120   ModPtr module_entry = pkg->module();
   120   if (module_entry == NULL || !module_entry->is_named()) {
   121   if (module_entry == NULL) {
   121     return 0;
   122     return 0;
   122   }
   123   }
   123   if (leakp) {
   124   if (leakp) {
   124     SET_LEAKP(module_entry);
   125     SET_LEAKP(module_entry);
   125   } else {
   126   } else {
   134   return METHOD_ID(klass, method);
   135   return METHOD_ID(klass, method);
   135 }
   136 }
   136 
   137 
   137 static traceid cld_id(CldPtr cld, bool leakp) {
   138 static traceid cld_id(CldPtr cld, bool leakp) {
   138   assert(cld != NULL, "invariant");
   139   assert(cld != NULL, "invariant");
   139   if (cld->is_unsafe_anonymous()) {
   140   assert(!cld->is_unsafe_anonymous(), "invariant");
   140     return 0;
       
   141   }
       
   142   if (leakp) {
   141   if (leakp) {
   143     SET_LEAKP(cld);
   142     SET_LEAKP(cld);
   144   } else {
   143   } else {
   145     SET_TRANSIENT(cld);
   144     SET_TRANSIENT(cld);
   146   }
   145   }
   149 
   148 
   150 template <typename T>
   149 template <typename T>
   151 static s4 get_flags(const T* ptr) {
   150 static s4 get_flags(const T* ptr) {
   152   assert(ptr != NULL, "invariant");
   151   assert(ptr != NULL, "invariant");
   153   return ptr->access_flags().get_flags();
   152   return ptr->access_flags().get_flags();
       
   153 }
       
   154 
       
   155 static bool is_unsafe_anonymous(const Klass* klass) {
       
   156   assert(klass != NULL, "invariant");
       
   157   return klass->is_instance_klass() && ((const InstanceKlass*)klass)->is_unsafe_anonymous();
       
   158 }
       
   159 
       
   160 static ClassLoaderData* get_cld(const Klass* klass) {
       
   161   assert(klass != NULL, "invariant");
       
   162   return is_unsafe_anonymous(klass) ?
       
   163     InstanceKlass::cast(klass)->unsafe_anonymous_host()->class_loader_data() : klass->class_loader_data();
   154 }
   164 }
   155 
   165 
   156 template <typename T>
   166 template <typename T>
   157 static void set_serialized(const T* ptr) {
   167 static void set_serialized(const T* ptr) {
   158   assert(ptr != NULL, "invariant");
   168   assert(ptr != NULL, "invariant");
   182     pkg_id = package_id(theklass, leakp);
   192     pkg_id = package_id(theklass, leakp);
   183   } else {
   193   } else {
   184     assert(theklass->is_typeArray_klass(), "invariant");
   194     assert(theklass->is_typeArray_klass(), "invariant");
   185   }
   195   }
   186   writer->write(artifact_id(klass));
   196   writer->write(artifact_id(klass));
   187   writer->write(cld_id(klass->class_loader_data(), leakp));
   197   writer->write(cld_id(get_cld(klass), leakp));
   188   writer->write(mark_symbol(klass, leakp));
   198   writer->write(mark_symbol(klass, leakp));
   189   writer->write(pkg_id);
   199   writer->write(pkg_id);
   190   writer->write(get_flags(klass));
   200   writer->write(get_flags(klass));
   191   return 1;
   201   return 1;
   192 }
   202 }
   536 
   546 
   537 static void do_class_loader_data(ClassLoaderData* cld) {
   547 static void do_class_loader_data(ClassLoaderData* cld) {
   538   do_previous_epoch_artifact(_subsystem_callback, cld);
   548   do_previous_epoch_artifact(_subsystem_callback, cld);
   539 }
   549 }
   540 
   550 
   541 class CldFieldSelector {
   551 class KlassCldFieldSelector {
   542  public:
   552  public:
   543   typedef CldPtr TypePtr;
   553   typedef CldPtr TypePtr;
   544   static TypePtr select(KlassPtr klass) {
   554   static TypePtr select(KlassPtr klass) {
   545     assert(klass != NULL, "invariant");
   555     assert(klass != NULL, "invariant");
   546     CldPtr cld = klass->class_loader_data();
   556     return get_cld(klass);
   547     return cld->is_unsafe_anonymous() ? NULL : cld;
   557   }
       
   558 };
       
   559 
       
   560 class ModuleCldFieldSelector {
       
   561 public:
       
   562   typedef CldPtr TypePtr;
       
   563   static TypePtr select(KlassPtr klass) {
       
   564     assert(klass != NULL, "invariant");
       
   565     ModPtr mod = ModuleFieldSelector::select(klass);
       
   566     return mod != NULL ? mod->loader_data() : NULL;
   548   }
   567   }
   549 };
   568 };
   550 
   569 
   551 class CLDCallback : public CLDClosure {
   570 class CLDCallback : public CLDClosure {
   552  public:
   571  public:
   568 typedef SerializePredicate<CldPtr> CldPredicate;
   587 typedef SerializePredicate<CldPtr> CldPredicate;
   569 typedef JfrPredicatedTypeWriterImplHost<CldPtr, CldPredicate, write__classloader> CldWriterImpl;
   588 typedef JfrPredicatedTypeWriterImplHost<CldPtr, CldPredicate, write__classloader> CldWriterImpl;
   570 typedef JfrTypeWriterHost<CldWriterImpl, TYPE_CLASSLOADER> CldWriter;
   589 typedef JfrTypeWriterHost<CldWriterImpl, TYPE_CLASSLOADER> CldWriter;
   571 typedef CompositeFunctor<CldPtr, CldWriter, ClearArtifact<CldPtr> > CldWriterWithClear;
   590 typedef CompositeFunctor<CldPtr, CldWriter, ClearArtifact<CldPtr> > CldWriterWithClear;
   572 typedef JfrArtifactCallbackHost<CldPtr, CldWriterWithClear> CldCallback;
   591 typedef JfrArtifactCallbackHost<CldPtr, CldWriterWithClear> CldCallback;
   573 typedef KlassToFieldEnvelope<CldFieldSelector, CldWriter> KlassCldWriter;
   592 typedef KlassToFieldEnvelope<KlassCldFieldSelector, CldWriter> KlassCldWriter;
       
   593 typedef KlassToFieldEnvelope<ModuleCldFieldSelector, CldWriter> ModuleCldWriter;
       
   594 typedef CompositeFunctor<KlassPtr, KlassCldWriter, ModuleCldWriter> KlassAndModuleCldWriter;
   574 
   595 
   575 typedef LeakPredicate<CldPtr> LeakCldPredicate;
   596 typedef LeakPredicate<CldPtr> LeakCldPredicate;
   576 typedef JfrPredicatedTypeWriterImplHost<CldPtr, LeakCldPredicate, write__classloader__leakp> LeakCldWriterImpl;
   597 typedef JfrPredicatedTypeWriterImplHost<CldPtr, LeakCldPredicate, write__classloader__leakp> LeakCldWriterImpl;
   577 typedef JfrTypeWriterHost<LeakCldWriterImpl, TYPE_CLASSLOADER> LeakCldWriter;
   598 typedef JfrTypeWriterHost<LeakCldWriterImpl, TYPE_CLASSLOADER> LeakCldWriter;
   578 
   599 
   579 typedef CompositeFunctor<CldPtr, LeakCldWriter, CldWriter> CompositeCldWriter;
   600 typedef CompositeFunctor<CldPtr, LeakCldWriter, CldWriter> CompositeCldWriter;
   580 typedef KlassToFieldEnvelope<CldFieldSelector, CompositeCldWriter> KlassCompositeCldWriter;
   601 typedef KlassToFieldEnvelope<KlassCldFieldSelector, CompositeCldWriter> KlassCompositeCldWriter;
       
   602 typedef KlassToFieldEnvelope<ModuleCldFieldSelector, CompositeCldWriter> ModuleCompositeCldWriter;
       
   603 typedef CompositeFunctor<KlassPtr, KlassCompositeCldWriter, ModuleCompositeCldWriter> KlassAndModuleCompositeCldWriter;
   581 typedef CompositeFunctor<CldPtr, CompositeCldWriter, ClearArtifact<CldPtr> > CompositeCldWriterWithClear;
   604 typedef CompositeFunctor<CldPtr, CompositeCldWriter, ClearArtifact<CldPtr> > CompositeCldWriterWithClear;
   582 typedef JfrArtifactCallbackHost<CldPtr, CompositeCldWriterWithClear> CompositeCldCallback;
   605 typedef JfrArtifactCallbackHost<CldPtr, CompositeCldWriterWithClear> CompositeCldCallback;
   583 
   606 
   584 static void write_classloaders() {
   607 static void write_classloaders() {
   585   assert(_writer != NULL, "invariant");
   608   assert(_writer != NULL, "invariant");
   586   CldWriter cldw(_writer, _class_unload);
   609   CldWriter cldw(_writer, _class_unload);
   587   KlassCldWriter kcw(&cldw);
   610   KlassCldWriter kcw(&cldw);
       
   611   ModuleCldWriter mcw(&cldw);
       
   612   KlassAndModuleCldWriter kmcw(&kcw, &mcw);
   588   if (current_epoch()) {
   613   if (current_epoch()) {
   589     _artifacts->iterate_klasses(kcw);
   614     _artifacts->iterate_klasses(kmcw);
   590     _artifacts->tally(cldw);
   615     _artifacts->tally(cldw);
   591     return;
   616     return;
   592   }
   617   }
   593   assert(previous_epoch(), "invariant");
   618   assert(previous_epoch(), "invariant");
   594   if (_leakp_writer == NULL) {
   619   if (_leakp_writer == NULL) {
   595     _artifacts->iterate_klasses(kcw);
   620     _artifacts->iterate_klasses(kmcw);
   596     ClearArtifact<CldPtr> clear;
   621     ClearArtifact<CldPtr> clear;
   597     CldWriterWithClear cldwwc(&cldw, &clear);
   622     CldWriterWithClear cldwwc(&cldw, &clear);
   598     CldCallback callback(&cldwwc);
   623     CldCallback callback(&cldwwc);
   599     _subsystem_callback = &callback;
   624     _subsystem_callback = &callback;
   600     do_class_loaders();
   625     do_class_loaders();
   601   } else {
   626   } else {
   602     LeakCldWriter lcldw(_leakp_writer, _class_unload);
   627     LeakCldWriter lcldw(_leakp_writer, _class_unload);
   603     CompositeCldWriter ccldw(&lcldw, &cldw);
   628     CompositeCldWriter ccldw(&lcldw, &cldw);
   604     KlassCompositeCldWriter kccldw(&ccldw);
   629     KlassCompositeCldWriter kccldw(&ccldw);
   605     _artifacts->iterate_klasses(kccldw);
   630     ModuleCompositeCldWriter mccldw(&ccldw);
       
   631     KlassAndModuleCompositeCldWriter kmccldw(&kccldw, &mccldw);
       
   632     _artifacts->iterate_klasses(kmccldw);
   606     ClearArtifact<CldPtr> clear;
   633     ClearArtifact<CldPtr> clear;
   607     CompositeCldWriterWithClear ccldwwc(&ccldw, &clear);
   634     CompositeCldWriterWithClear ccldwwc(&ccldw, &clear);
   608     CompositeCldCallback callback(&ccldwwc);
   635     CompositeCldCallback callback(&ccldwwc);
   609     _subsystem_callback = &callback;
   636     _subsystem_callback = &callback;
   610     do_class_loaders();
   637     do_class_loaders();
   650   assert(m != NULL, "invariant");
   677   assert(m != NULL, "invariant");
   651   MethodPtr method = (MethodPtr)m;
   678   MethodPtr method = (MethodPtr)m;
   652   return write_method(writer, method, true);
   679   return write_method(writer, method, true);
   653 }
   680 }
   654 
   681 
   655 template <typename MethodCallback, typename KlassCallback, bool leakp>
   682 class BitMapFilter {
       
   683   ResourceBitMap _bitmap;
       
   684  public:
       
   685   explicit BitMapFilter(int length = 0) : _bitmap((size_t)length) {}
       
   686   bool operator()(size_t idx) {
       
   687     if (_bitmap.size() == 0) {
       
   688       return true;
       
   689     }
       
   690     if (_bitmap.at(idx)) {
       
   691       return false;
       
   692     }
       
   693     _bitmap.set_bit(idx);
       
   694     return true;
       
   695   }
       
   696 };
       
   697 
       
   698 class AlwaysTrue {
       
   699  public:
       
   700   explicit AlwaysTrue(int length = 0) {}
       
   701   bool operator()(size_t idx) {
       
   702     return true;
       
   703   }
       
   704 };
       
   705 
       
   706 template <typename MethodCallback, typename KlassCallback, class Filter, bool leakp>
   656 class MethodIteratorHost {
   707 class MethodIteratorHost {
   657  private:
   708  private:
   658   MethodCallback _method_cb;
   709   MethodCallback _method_cb;
   659   KlassCallback _klass_cb;
   710   KlassCallback _klass_cb;
   660   MethodUsedPredicate<leakp> _method_used_predicate;
   711   MethodUsedPredicate<leakp> _method_used_predicate;
   669     _method_used_predicate(current_epoch),
   720     _method_used_predicate(current_epoch),
   670     _method_flag_predicate(current_epoch) {}
   721     _method_flag_predicate(current_epoch) {}
   671 
   722 
   672   bool operator()(KlassPtr klass) {
   723   bool operator()(KlassPtr klass) {
   673     if (_method_used_predicate(klass)) {
   724     if (_method_used_predicate(klass)) {
   674       const InstanceKlass* const ik = InstanceKlass::cast(klass);
   725       const InstanceKlass* ik = InstanceKlass::cast(klass);
   675       const int len = ik->methods()->length();
   726       const int len = ik->methods()->length();
   676       for (int i = 0; i < len; ++i) {
   727       Filter filter(ik->previous_versions() != NULL ? len : 0);
   677         MethodPtr method = ik->methods()->at(i);
   728       while (ik != NULL) {
   678         if (_method_flag_predicate(method)) {
   729         for (int i = 0; i < len; ++i) {
   679           _method_cb(method);
   730           MethodPtr method = ik->methods()->at(i);
       
   731           if (_method_flag_predicate(method) && filter(i)) {
       
   732             _method_cb(method);
       
   733           }
   680         }
   734         }
       
   735         // There can be multiple versions of the same method running
       
   736         // due to redefinition. Need to inspect the complete set of methods.
       
   737         ik = ik->previous_versions();
   681       }
   738       }
   682     }
   739     }
   683     return _klass_cb(klass);
   740     return _klass_cb(klass);
   684   }
   741   }
   685 
   742 
   695   bool operator()(T const& value) {
   752   bool operator()(T const& value) {
   696     return _t(value);
   753     return _t(value);
   697   }
   754   }
   698 };
   755 };
   699 
   756 
       
   757 template <typename T>
       
   758 class EmptyStub {
       
   759  public:
       
   760   bool operator()(T const& value) { return true; }
       
   761 };
       
   762 
   700 typedef SerializePredicate<MethodPtr> MethodPredicate;
   763 typedef SerializePredicate<MethodPtr> MethodPredicate;
   701 typedef JfrPredicatedTypeWriterImplHost<MethodPtr, MethodPredicate, write__method> MethodWriterImplTarget;
   764 typedef JfrPredicatedTypeWriterImplHost<MethodPtr, MethodPredicate, write__method> MethodWriterImplTarget;
   702 typedef Wrapper<KlassPtr, Stub> KlassCallbackStub;
   765 typedef Wrapper<KlassPtr, EmptyStub> KlassCallbackStub;
   703 typedef JfrTypeWriterHost<MethodWriterImplTarget, TYPE_METHOD> MethodWriterImpl;
   766 typedef JfrTypeWriterHost<MethodWriterImplTarget, TYPE_METHOD> MethodWriterImpl;
   704 typedef MethodIteratorHost<MethodWriterImpl, KlassCallbackStub, false> MethodWriter;
   767 typedef MethodIteratorHost<MethodWriterImpl, KlassCallbackStub, BitMapFilter, false> MethodWriter;
   705 
   768 
   706 typedef LeakPredicate<MethodPtr> LeakMethodPredicate;
   769 typedef LeakPredicate<MethodPtr> LeakMethodPredicate;
   707 typedef JfrPredicatedTypeWriterImplHost<MethodPtr, LeakMethodPredicate, write__method__leakp> LeakMethodWriterImplTarget;
   770 typedef JfrPredicatedTypeWriterImplHost<MethodPtr, LeakMethodPredicate, write__method__leakp> LeakMethodWriterImplTarget;
   708 typedef JfrTypeWriterHost<LeakMethodWriterImplTarget, TYPE_METHOD> LeakMethodWriterImpl;
   771 typedef JfrTypeWriterHost<LeakMethodWriterImplTarget, TYPE_METHOD> LeakMethodWriterImpl;
   709 typedef MethodIteratorHost<LeakMethodWriterImpl, KlassCallbackStub, true> LeakMethodWriter;
   772 typedef MethodIteratorHost<LeakMethodWriterImpl, KlassCallbackStub, BitMapFilter, true> LeakMethodWriter;
       
   773 typedef MethodIteratorHost<LeakMethodWriterImpl, KlassCallbackStub, BitMapFilter, true> LeakMethodWriter;
   710 typedef CompositeFunctor<KlassPtr, LeakMethodWriter, MethodWriter> CompositeMethodWriter;
   774 typedef CompositeFunctor<KlassPtr, LeakMethodWriter, MethodWriter> CompositeMethodWriter;
   711 
   775 
   712 static void write_methods() {
   776 static void write_methods() {
   713   assert(_writer != NULL, "invariant");
   777   assert(_writer != NULL, "invariant");
   714   MethodWriter mw(_writer, current_epoch(), _class_unload);
   778   MethodWriter mw(_writer, current_epoch(), _class_unload);
   830   clear_artifacts = true;
   894   clear_artifacts = true;
   831 }
   895 }
   832 
   896 
   833 typedef Wrapper<KlassPtr, ClearArtifact> ClearKlassBits;
   897 typedef Wrapper<KlassPtr, ClearArtifact> ClearKlassBits;
   834 typedef Wrapper<MethodPtr, ClearArtifact> ClearMethodFlag;
   898 typedef Wrapper<MethodPtr, ClearArtifact> ClearMethodFlag;
   835 typedef MethodIteratorHost<ClearMethodFlag, ClearKlassBits, false> ClearKlassAndMethods;
   899 typedef MethodIteratorHost<ClearMethodFlag, ClearKlassBits, AlwaysTrue, false> ClearKlassAndMethods;
   836 
   900 
   837 static size_t teardown() {
   901 static size_t teardown() {
   838   assert(_artifacts != NULL, "invariant");
   902   assert(_artifacts != NULL, "invariant");
   839   const size_t total_count = _artifacts->total_count();
   903   const size_t total_count = _artifacts->total_count();
   840   if (previous_epoch()) {
   904   if (previous_epoch()) {