src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp
changeset 58863 c16ac7a2eba4
parent 54964 ec7d6d8effc7
child 59247 56bf71d64d51
equal deleted inserted replaced
58861:2c3cc4b01880 58863:c16ac7a2eba4
    31 #include "jfr/recorder/storage/jfrStorageUtils.inline.hpp"
    31 #include "jfr/recorder/storage/jfrStorageUtils.inline.hpp"
    32 #include "jfr/recorder/stringpool/jfrStringPool.hpp"
    32 #include "jfr/recorder/stringpool/jfrStringPool.hpp"
    33 #include "jfr/recorder/stringpool/jfrStringPoolWriter.hpp"
    33 #include "jfr/recorder/stringpool/jfrStringPoolWriter.hpp"
    34 #include "jfr/utilities/jfrTypes.hpp"
    34 #include "jfr/utilities/jfrTypes.hpp"
    35 #include "logging/log.hpp"
    35 #include "logging/log.hpp"
    36 #include "runtime/atomic.hpp"
       
    37 #include "runtime/mutexLocker.hpp"
    36 #include "runtime/mutexLocker.hpp"
    38 #include "runtime/orderAccess.hpp"
    37 #include "runtime/orderAccess.hpp"
    39 #include "runtime/safepoint.hpp"
    38 #include "runtime/safepoint.hpp"
    40 #include "runtime/thread.inline.hpp"
    39 #include "runtime/thread.inline.hpp"
    41 
    40 
    42 typedef JfrStringPool::Buffer* BufferPtr;
    41 typedef JfrStringPool::Buffer* BufferPtr;
    43 
    42 
    44 static JfrStringPool* _instance = NULL;
    43 static JfrStringPool* _instance = NULL;
       
    44 static uint64_t store_generation = 0;
       
    45 static uint64_t serialized_generation = 0;
       
    46 
       
    47 inline void set_generation(uint64_t value, uint64_t* const dest) {
       
    48   assert(dest != NULL, "invariant");
       
    49   OrderAccess::release_store(dest, value);
       
    50 }
       
    51 static void increment_store_generation() {
       
    52   const uint64_t current_serialized = OrderAccess::load_acquire(&serialized_generation);
       
    53   const uint64_t current_stored = OrderAccess::load_acquire(&store_generation);
       
    54   if (current_serialized == current_stored) {
       
    55     set_generation(current_serialized + 1, &store_generation);
       
    56   }
       
    57 }
       
    58 
       
    59 static bool increment_serialized_generation() {
       
    60   const uint64_t current_stored = OrderAccess::load_acquire(&store_generation);
       
    61   const uint64_t current_serialized = OrderAccess::load_acquire(&serialized_generation);
       
    62   if (current_stored != current_serialized) {
       
    63     set_generation(current_stored, &serialized_generation);
       
    64     return true;
       
    65   }
       
    66   return false;
       
    67 }
       
    68 
       
    69 bool JfrStringPool::is_modified() {
       
    70   return increment_serialized_generation();
       
    71 }
    45 
    72 
    46 JfrStringPool& JfrStringPool::instance() {
    73 JfrStringPool& JfrStringPool::instance() {
    47   return *_instance;
    74   return *_instance;
    48 }
    75 }
    49 
    76 
    50 JfrStringPool* JfrStringPool::create(JfrChunkWriter& cw) {
    77 JfrStringPool* JfrStringPool::create(JfrChunkWriter& cw) {
       
    78   store_generation = 0;
       
    79   serialized_generation = 0;
    51   assert(_instance == NULL, "invariant");
    80   assert(_instance == NULL, "invariant");
    52   _instance = new JfrStringPool(cw);
    81   _instance = new JfrStringPool(cw);
    53   return _instance;
    82   return _instance;
    54 }
    83 }
    55 
    84 
   129 }
   158 }
   130 
   159 
   131 bool JfrStringPool::add(bool epoch, jlong id, jstring string, JavaThread* jt) {
   160 bool JfrStringPool::add(bool epoch, jlong id, jstring string, JavaThread* jt) {
   132   assert(jt != NULL, "invariant");
   161   assert(jt != NULL, "invariant");
   133   const bool current_epoch = JfrTraceIdEpoch::epoch();
   162   const bool current_epoch = JfrTraceIdEpoch::epoch();
   134   if (current_epoch == epoch) {
   163   if (current_epoch != epoch) {
       
   164     return current_epoch;
       
   165   }
       
   166   {
   135     JfrStringPoolWriter writer(jt);
   167     JfrStringPoolWriter writer(jt);
   136     writer.write(id);
   168     writer.write(id);
   137     writer.write(string);
   169     writer.write(string);
   138     writer.inc_nof_strings();
   170     writer.inc_nof_strings();
   139   }
   171   }
       
   172   increment_store_generation();
   140   return current_epoch;
   173   return current_epoch;
   141 }
   174 }
   142 
   175 
   143 template <template <typename> class Operation>
   176 template <template <typename> class Operation>
   144 class StringPoolOp {
   177 class StringPoolOp {
   161     return _op.write(buffer, data, size);
   194     return _op.write(buffer, data, size);
   162   }
   195   }
   163   size_t processed() { return _strings_processed; }
   196   size_t processed() { return _strings_processed; }
   164 };
   197 };
   165 
   198 
   166 template <typename Type>
   199 template <typename T>
   167 class StringPoolDiscarderStub {
   200 class StringPoolDiscarderStub {
   168  public:
   201  public:
       
   202   typedef T Type;
   169   bool write(Type* buffer, const u1* data, size_t size) {
   203   bool write(Type* buffer, const u1* data, size_t size) {
   170     // stub only, discard happens at higher level
   204     // stub only, discard happens at higher level
   171     return true;
   205     return true;
   172   }
   206   }
   173 };
   207 };
   195   assert(SafepointSynchronize::is_at_safepoint(), "invariant");
   229   assert(SafepointSynchronize::is_at_safepoint(), "invariant");
   196   return write();
   230   return write();
   197 }
   231 }
   198 
   232 
   199 size_t JfrStringPool::clear() {
   233 size_t JfrStringPool::clear() {
       
   234   increment_serialized_generation();
   200   DiscardOperation discard_operation;
   235   DiscardOperation discard_operation;
   201   ExclusiveDiscardOperation edo(discard_operation);
   236   ExclusiveDiscardOperation edo(discard_operation);
   202   StringPoolReleaseOperation spro(_free_list_mspace, Thread::current(), false);
   237   StringPoolReleaseOperation spro(_free_list_mspace, Thread::current(), false);
   203   StringPoolDiscardOperation spdo(&edo, &spro);
   238   StringPoolDiscardOperation spdo(&edo, &spro);
   204   assert(_free_list_mspace->is_full_empty(), "invariant");
   239   assert(_free_list_mspace->is_full_empty(), "invariant");