src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeManager.cpp
changeset 58863 c16ac7a2eba4
parent 58786 7909763ad193
equal deleted inserted replaced
58861:2c3cc4b01880 58863:c16ac7a2eba4
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 #include "jfr/metadata/jfrSerializer.hpp"
    26 #include "jfr/metadata/jfrSerializer.hpp"
    27 #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp"
    27 #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp"
    28 #include "jfr/recorder/checkpoint/types/jfrType.hpp"
    28 #include "jfr/recorder/checkpoint/types/jfrType.hpp"
    29 #include "jfr/recorder/checkpoint/types/jfrTypeManager.hpp"
    29 #include "jfr/recorder/checkpoint/types/jfrTypeManager.hpp"
       
    30 #include "jfr/recorder/jfrRecorder.hpp"
    30 #include "jfr/utilities/jfrDoublyLinkedList.hpp"
    31 #include "jfr/utilities/jfrDoublyLinkedList.hpp"
    31 #include "jfr/utilities/jfrIterator.hpp"
    32 #include "jfr/utilities/jfrIterator.hpp"
    32 #include "memory/resourceArea.hpp"
    33 #include "memory/resourceArea.hpp"
    33 #include "runtime/handles.inline.hpp"
    34 #include "runtime/handles.inline.hpp"
    34 #include "runtime/safepoint.hpp"
    35 #include "runtime/safepoint.hpp"
    71 
    72 
    72   JfrTypeId id() const {
    73   JfrTypeId id() const {
    73     return _id;
    74     return _id;
    74   }
    75   }
    75 
    76 
    76   void invoke(JfrCheckpointWriter& writer) const;
    77   void on_rotation() const {
       
    78     _serializer->on_rotation();
       
    79   }
       
    80 
       
    81   void invoke(JfrCheckpointWriter& writer) const {
       
    82     if (_cache.valid()) {
       
    83       writer.increment();
       
    84       _cache->write(writer);
       
    85       return;
       
    86     }
       
    87     const JfrCheckpointContext ctx = writer.context();
       
    88     // serialize the type id before invoking callback
       
    89     writer.write_type(_id);
       
    90     const intptr_t start = writer.current_offset();
       
    91     // invoke the serializer routine
       
    92     _serializer->serialize(writer);
       
    93     if (start == writer.current_offset()) {
       
    94       // the serializer implementation did nothing, rewind to restore
       
    95       writer.set_context(ctx);
       
    96       return;
       
    97     }
       
    98     if (_permit_cache) {
       
    99       _cache = writer.copy(&ctx);
       
   100     }
       
   101   }
    77 };
   102 };
    78 
   103 
    79 void JfrSerializerRegistration::invoke(JfrCheckpointWriter& writer) const {
   104 static void serialize_threads(JfrCheckpointWriter& writer) {
    80   if (_cache.valid()) {
   105   JfrThreadConstantSet thread_set;
    81     writer.increment();
   106   writer.write_type(TYPE_THREAD);
    82     _cache->write(writer);
   107   thread_set.serialize(writer);
    83     return;
   108 }
    84   }
   109 
    85   const JfrCheckpointContext ctx = writer.context();
   110 static void serialize_thread_groups(JfrCheckpointWriter& writer) {
    86   // serialize the type id before invoking callback
   111   JfrThreadGroupConstant thread_group_set;
    87   writer.write_type(_id);
   112   writer.write_type(TYPE_THREADGROUP);
    88   const intptr_t start = writer.current_offset();
   113   thread_group_set.serialize(writer);
    89   // invoke the serializer routine
   114 }
    90   _serializer->serialize(writer);
   115 
    91   if (start == writer.current_offset() ) {
   116 void JfrTypeManager::write_threads(JfrCheckpointWriter& writer) {
    92     // the serializer implementation did nothing, rewind to restore
   117   serialize_threads(writer);
    93     writer.set_context(ctx);
   118   serialize_thread_groups(writer);
    94     return;
   119 }
    95   }
   120 
    96   if (_permit_cache) {
   121 void JfrTypeManager::create_thread_blob(Thread* t) {
    97     _cache = writer.copy(&ctx);
   122   assert(t != NULL, "invariant");
    98   }
   123   ResourceMark rm(t);
       
   124   HandleMark hm(t);
       
   125   JfrThreadConstant type_thread(t);
       
   126   JfrCheckpointWriter writer(t, true, THREADS);
       
   127   writer.write_type(TYPE_THREAD);
       
   128   type_thread.serialize(writer);
       
   129   // create and install a checkpoint blob
       
   130   t->jfr_thread_local()->set_thread_blob(writer.move());
       
   131   assert(t->jfr_thread_local()->has_thread_blob(), "invariant");
       
   132 }
       
   133 
       
   134 void JfrTypeManager::write_thread_checkpoint(Thread* t) {
       
   135   assert(t != NULL, "invariant");
       
   136   ResourceMark rm(t);
       
   137   HandleMark hm(t);
       
   138   JfrThreadConstant type_thread(t);
       
   139   JfrCheckpointWriter writer(t, true, THREADS);
       
   140   writer.write_type(TYPE_THREAD);
       
   141   type_thread.serialize(writer);
    99 }
   142 }
   100 
   143 
   101 class SerializerRegistrationGuard : public StackObj {
   144 class SerializerRegistrationGuard : public StackObj {
   102  private:
   145  private:
   103   static Semaphore _mutex_semaphore;
   146   static Semaphore _mutex_semaphore;
   113 Semaphore SerializerRegistrationGuard::_mutex_semaphore(1);
   156 Semaphore SerializerRegistrationGuard::_mutex_semaphore(1);
   114 
   157 
   115 typedef JfrDoublyLinkedList<JfrSerializerRegistration> List;
   158 typedef JfrDoublyLinkedList<JfrSerializerRegistration> List;
   116 typedef StopOnNullIterator<const List> Iterator;
   159 typedef StopOnNullIterator<const List> Iterator;
   117 static List types;
   160 static List types;
   118 static List safepoint_types;
       
   119 
   161 
   120 void JfrTypeManager::destroy() {
   162 void JfrTypeManager::destroy() {
   121   SerializerRegistrationGuard guard;
   163   SerializerRegistrationGuard guard;
   122   Iterator iter(types);
   164   Iterator iter(types);
   123   JfrSerializerRegistration* registration;
   165   JfrSerializerRegistration* registration;
   124   while (iter.has_next()) {
   166   while (iter.has_next()) {
   125     registration = types.remove(iter.next());
   167     registration = types.remove(iter.next());
   126     assert(registration != NULL, "invariant");
   168     assert(registration != NULL, "invariant");
   127     delete registration;
   169     delete registration;
   128   }
   170   }
   129   Iterator sp_type_iter(safepoint_types);
   171 }
   130   while (sp_type_iter.has_next()) {
   172 
   131     registration = safepoint_types.remove(sp_type_iter.next());
   173 void JfrTypeManager::on_rotation() {
   132     assert(registration != NULL, "invariant");
       
   133     delete registration;
       
   134   }
       
   135 }
       
   136 
       
   137 void JfrTypeManager::write_types(JfrCheckpointWriter& writer) {
       
   138   const Iterator iter(types);
   174   const Iterator iter(types);
   139   while (iter.has_next()) {
   175   while (iter.has_next()) {
   140     iter.next()->invoke(writer);
   176     iter.next()->on_rotation();
   141   }
   177   }
   142 }
       
   143 
       
   144 void JfrTypeManager::write_safepoint_types(JfrCheckpointWriter& writer) {
       
   145   assert(SafepointSynchronize::is_at_safepoint(), "invariant");
       
   146   const Iterator iter(safepoint_types);
       
   147   while (iter.has_next()) {
       
   148     iter.next()->invoke(writer);
       
   149   }
       
   150 }
       
   151 
       
   152 void JfrTypeManager::create_thread_blob(JavaThread* jt) {
       
   153   assert(jt != NULL, "invariant");
       
   154   ResourceMark rm(jt);
       
   155   HandleMark hm(jt);
       
   156   JfrThreadConstant type_thread(jt);
       
   157   JfrCheckpointWriter writer(false, true, jt);
       
   158   writer.write_type(TYPE_THREAD);
       
   159   type_thread.serialize(writer);
       
   160   // create and install a checkpoint blob
       
   161   jt->jfr_thread_local()->set_thread_blob(writer.move());
       
   162   assert(jt->jfr_thread_local()->has_thread_blob(), "invariant");
       
   163 }
       
   164 
       
   165 void JfrTypeManager::write_thread_checkpoint(JavaThread* jt) {
       
   166   assert(jt != NULL, "JavaThread is NULL!");
       
   167   ResourceMark rm(jt);
       
   168   HandleMark hm(jt);
       
   169   JfrThreadConstant type_thread(jt);
       
   170   JfrCheckpointWriter writer(false, true, jt);
       
   171   writer.write_type(TYPE_THREAD);
       
   172   type_thread.serialize(writer);
       
   173 }
   178 }
   174 
   179 
   175 #ifdef ASSERT
   180 #ifdef ASSERT
   176 static void assert_not_registered_twice(JfrTypeId id, List& list) {
   181 static void assert_not_registered_twice(JfrTypeId id, List& list) {
   177   const Iterator iter(list);
   182   const Iterator iter(list);
   179     assert(iter.next()->id() != id, "invariant");
   184     assert(iter.next()->id() != id, "invariant");
   180   }
   185   }
   181 }
   186 }
   182 #endif
   187 #endif
   183 
   188 
   184 static bool register_type(JfrTypeId id, bool require_safepoint, bool permit_cache, JfrSerializer* serializer) {
   189 static bool new_registration = false;
       
   190 
       
   191 static bool register_static_type(JfrTypeId id, bool permit_cache, JfrSerializer* serializer) {
   185   assert(serializer != NULL, "invariant");
   192   assert(serializer != NULL, "invariant");
   186   JfrSerializerRegistration* const registration = new JfrSerializerRegistration(id, permit_cache, serializer);
   193   JfrSerializerRegistration* const registration = new JfrSerializerRegistration(id, permit_cache, serializer);
   187   if (registration == NULL) {
   194   if (registration == NULL) {
   188     delete serializer;
   195     delete serializer;
   189     return false;
   196     return false;
   190   }
   197   }
   191   if (require_safepoint) {
   198   assert(!types.in_list(registration), "invariant");
   192     assert(!safepoint_types.in_list(registration), "invariant");
   199   DEBUG_ONLY(assert_not_registered_twice(id, types);)
   193     DEBUG_ONLY(assert_not_registered_twice(id, safepoint_types);)
   200   if (JfrRecorder::is_recording()) {
   194     safepoint_types.prepend(registration);
   201     JfrCheckpointWriter writer(STATICS);
   195   } else {
   202     registration->invoke(writer);
   196     assert(!types.in_list(registration), "invariant");
   203     new_registration = true;
   197     DEBUG_ONLY(assert_not_registered_twice(id, types);)
   204   }
   198     types.prepend(registration);
   205   types.prepend(registration);
   199   }
       
   200   return true;
   206   return true;
   201 }
   207 }
   202 
   208 
   203 bool JfrTypeManager::initialize() {
   209 bool JfrTypeManager::initialize() {
   204   SerializerRegistrationGuard guard;
   210   SerializerRegistrationGuard guard;
   205 
   211   register_static_type(TYPE_FLAGVALUEORIGIN, true, new FlagValueOriginConstant());
   206   // register non-safepointing type serialization
   212   register_static_type(TYPE_INFLATECAUSE, true, new MonitorInflateCauseConstant());
   207   register_type(TYPE_FLAGVALUEORIGIN, false, true, new FlagValueOriginConstant());
   213   register_static_type(TYPE_GCCAUSE, true, new GCCauseConstant());
   208   register_type(TYPE_INFLATECAUSE, false, true, new MonitorInflateCauseConstant());
   214   register_static_type(TYPE_GCNAME, true, new GCNameConstant());
   209   register_type(TYPE_GCCAUSE, false, true, new GCCauseConstant());
   215   register_static_type(TYPE_GCWHEN, true, new GCWhenConstant());
   210   register_type(TYPE_GCNAME, false, true, new GCNameConstant());
   216   register_static_type(TYPE_GCTHRESHOLDUPDATER, true, new GCThresholdUpdaterConstant());
   211   register_type(TYPE_GCWHEN, false, true, new GCWhenConstant());
   217   register_static_type(TYPE_METADATATYPE, true, new MetadataTypeConstant());
   212   register_type(TYPE_GCTHRESHOLDUPDATER, false, true, new GCThresholdUpdaterConstant());
   218   register_static_type(TYPE_METASPACEOBJECTTYPE, true, new MetaspaceObjectTypeConstant());
   213   register_type(TYPE_METADATATYPE, false, true, new MetadataTypeConstant());
   219   register_static_type(TYPE_REFERENCETYPE, true, new ReferenceTypeConstant());
   214   register_type(TYPE_METASPACEOBJECTTYPE, false, true, new MetaspaceObjectTypeConstant());
   220   register_static_type(TYPE_NARROWOOPMODE, true, new NarrowOopModeConstant());
   215   register_type(TYPE_REFERENCETYPE, false, true, new ReferenceTypeConstant());
   221   register_static_type(TYPE_COMPILERPHASETYPE, true, new CompilerPhaseTypeConstant());
   216   register_type(TYPE_NARROWOOPMODE, false, true, new NarrowOopModeConstant());
   222   register_static_type(TYPE_CODEBLOBTYPE, true, new CodeBlobTypeConstant());
   217   register_type(TYPE_COMPILERPHASETYPE, false, true, new CompilerPhaseTypeConstant());
   223   register_static_type(TYPE_VMOPERATIONTYPE, true, new VMOperationTypeConstant());
   218   register_type(TYPE_CODEBLOBTYPE, false, true, new CodeBlobTypeConstant());
   224   register_static_type(TYPE_THREADSTATE, true, new ThreadStateConstant());
   219   register_type(TYPE_VMOPERATIONTYPE, false, true, new VMOperationTypeConstant());
       
   220   register_type(TYPE_THREADSTATE, false, true, new ThreadStateConstant());
       
   221 
       
   222   // register safepointing type serialization
       
   223   register_type(TYPE_THREADGROUP, true, false, new JfrThreadGroupConstant());
       
   224   register_type(TYPE_THREAD, true, false, new JfrThreadConstantSet());
       
   225   return true;
   225   return true;
   226 }
   226 }
   227 
   227 
   228 // implementation for the static registration function exposed in the JfrSerializer api
   228 // implementation for the static registration function exposed in the JfrSerializer api
   229 bool JfrSerializer::register_serializer(JfrTypeId id, bool require_safepoint, bool permit_cache, JfrSerializer* serializer) {
   229 bool JfrSerializer::register_serializer(JfrTypeId id, bool permit_cache, JfrSerializer* serializer) {
   230   SerializerRegistrationGuard guard;
   230   SerializerRegistrationGuard guard;
   231   return register_type(id, require_safepoint, permit_cache, serializer);
   231   return register_static_type(id, permit_cache, serializer);
   232 }
   232 }
       
   233 
       
   234 bool JfrTypeManager::has_new_static_type() {
       
   235   if (new_registration) {
       
   236     SerializerRegistrationGuard guard;
       
   237     new_registration = false;
       
   238     return true;
       
   239   }
       
   240   return false;
       
   241 }
       
   242 
       
   243 void JfrTypeManager::write_static_types(JfrCheckpointWriter& writer) {
       
   244   SerializerRegistrationGuard guard;
       
   245   const Iterator iter(types);
       
   246   while (iter.has_next()) {
       
   247     iter.next()->invoke(writer);
       
   248   }
       
   249   new_registration = false;
       
   250 }