src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp
branchJEP-349-branch
changeset 57870 00860d9caf4d
parent 57360 5d043a159d5c
child 57983 a57907813a83
equal deleted inserted replaced
57862:84ef29ccac56 57870:00860d9caf4d
    26 #include "jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp"
    26 #include "jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp"
    27 #include "oops/instanceKlass.hpp"
    27 #include "oops/instanceKlass.hpp"
    28 #include "oops/oop.inline.hpp"
    28 #include "oops/oop.inline.hpp"
    29 #include "oops/symbol.hpp"
    29 #include "oops/symbol.hpp"
    30 
    30 
    31 JfrSymbolId::JfrSymbolId() : _sym_table(new SymbolTable(this)), _cstring_table(new CStringTable(this)), _symbol_id_counter(0) {
    31 JfrSymbolId::JfrSymbolId() :
       
    32   _sym_table(new SymbolTable(this)),
       
    33   _cstring_table(new CStringTable(this)),
       
    34   _sym_list(NULL),
       
    35   _cstring_list(NULL),
       
    36   _symbol_id_counter(0),
       
    37   _class_unload(false) {
    32   assert(_sym_table != NULL, "invariant");
    38   assert(_sym_table != NULL, "invariant");
    33   assert(_cstring_table != NULL, "invariant");
    39   assert(_cstring_table != NULL, "invariant");
    34   initialize();
    40 }
    35 }
    41 
    36 
    42 JfrSymbolId::~JfrSymbolId() {
    37 void JfrSymbolId::initialize() {
       
    38   clear();
    43   clear();
    39   assert(_symbol_id_counter == 0, "invariant");
    44   delete _sym_table;
       
    45   delete _cstring_table;
    40 }
    46 }
    41 
    47 
    42 void JfrSymbolId::clear() {
    48 void JfrSymbolId::clear() {
    43   assert(_sym_table != NULL, "invariant");
    49   assert(_sym_table != NULL, "invariant");
    44   if (_sym_table->has_entries()) {
    50   if (_sym_table->has_entries()) {
    49   assert(_cstring_table != NULL, "invariant");
    55   assert(_cstring_table != NULL, "invariant");
    50   if (_cstring_table->has_entries()) {
    56   if (_cstring_table->has_entries()) {
    51     _cstring_table->clear_entries();
    57     _cstring_table->clear_entries();
    52   }
    58   }
    53   assert(!_cstring_table->has_entries(), "invariant");
    59   assert(!_cstring_table->has_entries(), "invariant");
       
    60 
       
    61   _sym_list = NULL;
       
    62   _cstring_list = NULL;
    54   _symbol_id_counter = 0;
    63   _symbol_id_counter = 0;
    55 }
    64 }
    56 
    65 
    57 JfrSymbolId::~JfrSymbolId() {
    66 void JfrSymbolId::set_class_unload(bool class_unload) {
    58   delete _sym_table;
    67   _class_unload = class_unload;
    59   delete _cstring_table;
       
    60 }
    68 }
    61 
    69 
    62 traceid JfrSymbolId::mark_unsafe_anonymous_klass_name(const Klass* k) {
    70 traceid JfrSymbolId::mark_unsafe_anonymous_klass_name(const Klass* k) {
    63   assert(k != NULL, "invariant");
    71   assert(k != NULL, "invariant");
    64   assert(k->is_instance_klass(), "invariant");
    72   assert(k->is_instance_klass(), "invariant");
    77   assert(mark(anonymous_symbol, anonymous_symbol_hash_code) == symbol_id, "invariant");
    85   assert(mark(anonymous_symbol, anonymous_symbol_hash_code) == symbol_id, "invariant");
    78   return symbol_id;
    86   return symbol_id;
    79 }
    87 }
    80 
    88 
    81 const JfrSymbolId::SymbolEntry* JfrSymbolId::map_symbol(const Symbol* symbol) const {
    89 const JfrSymbolId::SymbolEntry* JfrSymbolId::map_symbol(const Symbol* symbol) const {
    82   return _sym_table->lookup_only(symbol, (uintptr_t)const_cast<Symbol*>(symbol)->identity_hash());
    90   return _sym_table->lookup_only(symbol, (uintptr_t)symbol->identity_hash());
    83 }
    91 }
    84 
    92 
    85 const JfrSymbolId::SymbolEntry* JfrSymbolId::map_symbol(uintptr_t hash) const {
    93 const JfrSymbolId::SymbolEntry* JfrSymbolId::map_symbol(uintptr_t hash) const {
    86   return _sym_table->lookup_only(NULL, hash);
    94   return _sym_table->lookup_only(NULL, hash);
    87 }
    95 }
    88 
    96 
    89 const JfrSymbolId::CStringEntry* JfrSymbolId::map_cstring(uintptr_t hash) const {
    97 const JfrSymbolId::CStringEntry* JfrSymbolId::map_cstring(uintptr_t hash) const {
    90   return _cstring_table->lookup_only(NULL, hash);
    98   return _cstring_table->lookup_only(NULL, hash);
    91 }
    99 }
    92 
   100 
    93 void JfrSymbolId::assign_id(SymbolEntry* entry) {
   101 void JfrSymbolId::assign_id(const SymbolEntry* entry) {
    94   assert(entry != NULL, "invariant");
   102   assert(entry != NULL, "invariant");
       
   103   const_cast<Symbol*>(entry->literal())->increment_refcount();
    95   assert(entry->id() == 0, "invariant");
   104   assert(entry->id() == 0, "invariant");
    96   entry->set_id(++_symbol_id_counter);
   105   entry->set_id(++_symbol_id_counter);
       
   106   entry->set_list_next(_sym_list);
       
   107   _sym_list = entry;
    97 }
   108 }
    98 
   109 
    99 bool JfrSymbolId::equals(const Symbol* query, uintptr_t hash, const SymbolEntry* entry) {
   110 bool JfrSymbolId::equals(const Symbol* query, uintptr_t hash, const SymbolEntry* entry) {
   100   // query might be NULL
   111   // query might be NULL
   101   assert(entry != NULL, "invariant");
   112   assert(entry != NULL, "invariant");
   102   assert(entry->hash() == hash, "invariant");
   113   assert(entry->hash() == hash, "invariant");
   103   return true;
   114   return true;
   104 }
   115 }
   105 
   116 
   106 void JfrSymbolId::assign_id(CStringEntry* entry) {
   117 void JfrSymbolId::unlink(const SymbolEntry* entry) {
       
   118   assert(entry != NULL, "invariant");
       
   119   const_cast<Symbol*>(entry->literal())->decrement_refcount();
       
   120 }
       
   121 
       
   122 void JfrSymbolId::assign_id(const CStringEntry* entry) {
   107   assert(entry != NULL, "invariant");
   123   assert(entry != NULL, "invariant");
   108   assert(entry->id() == 0, "invariant");
   124   assert(entry->id() == 0, "invariant");
   109   entry->set_id(++_symbol_id_counter);
   125   entry->set_id(++_symbol_id_counter);
       
   126   entry->set_list_next(_cstring_list);
       
   127   _cstring_list = entry;
   110 }
   128 }
   111 
   129 
   112 bool JfrSymbolId::equals(const char* query, uintptr_t hash, const CStringEntry* entry) {
   130 bool JfrSymbolId::equals(const char* query, uintptr_t hash, const CStringEntry* entry) {
   113   // query might be NULL
   131   // query might be NULL
   114   assert(entry != NULL, "invariant");
   132   assert(entry != NULL, "invariant");
   115   assert(entry->hash() == hash, "invariant");
   133   assert(entry->hash() == hash, "invariant");
   116   return true;
   134   return true;
       
   135 }
       
   136 
       
   137 void JfrSymbolId::unlink(const CStringEntry* entry) {
       
   138   assert(entry != NULL, "invariant");
       
   139   if (entry->id() != 1) {
       
   140     FREE_C_HEAP_ARRAY(char, entry->literal());
       
   141   }
   117 }
   142 }
   118 
   143 
   119 traceid JfrSymbolId::mark(const Klass* k) {
   144 traceid JfrSymbolId::mark(const Klass* k) {
   120   assert(k != NULL, "invariant");
   145   assert(k != NULL, "invariant");
   121   traceid symbol_id = 0;
   146   traceid symbol_id = 0;
   122   if (is_unsafe_anonymous_klass(k)) {
   147   if (is_unsafe_anonymous_klass(k)) {
   123     symbol_id = mark_unsafe_anonymous_klass_name(k);
   148     symbol_id = mark_unsafe_anonymous_klass_name(k);
   124   }
   149   }
   125   if (0 == symbol_id) {
   150   if (0 == symbol_id) {
   126     const Symbol* const sym = k->name();
   151     Symbol* const sym = k->name();
   127     if (sym != NULL) {
   152     if (sym != NULL) {
   128       symbol_id = mark(sym);
   153       symbol_id = mark(sym);
   129     }
   154     }
   130   }
   155   }
   131   assert(symbol_id > 0, "a symbol handler must mark the symbol for writing");
   156   assert(symbol_id > 0, "a symbol handler must mark the symbol for writing");
   132   return symbol_id;
   157   return symbol_id;
   133 }
   158 }
   134 
   159 
   135 traceid JfrSymbolId::mark(const Symbol* symbol) {
   160 traceid JfrSymbolId::mark(const Symbol* symbol) {
   136   assert(symbol != NULL, "invariant");
   161   assert(symbol != NULL, "invariant");
   137   return mark(symbol, (uintptr_t)const_cast<Symbol*>(symbol)->identity_hash());
   162   return mark(symbol, (uintptr_t)symbol->identity_hash());
   138 }
   163 }
   139 
   164 
   140 traceid JfrSymbolId::mark(const Symbol* data, uintptr_t hash) {
   165 traceid JfrSymbolId::mark(const Symbol* data, uintptr_t hash) {
   141   assert(data != NULL, "invariant");
   166   assert(data != NULL, "invariant");
   142   assert(_sym_table != NULL, "invariant");
   167   assert(_sym_table != NULL, "invariant");
   143   return _sym_table->id(data, hash);
   168   const SymbolEntry& entry = _sym_table->lookup_put(data, hash);
       
   169   if (_class_unload) {
       
   170     entry.set_unloading();
       
   171   }
       
   172   return entry.id();
   144 }
   173 }
   145 
   174 
   146 traceid JfrSymbolId::mark(const char* str, uintptr_t hash) {
   175 traceid JfrSymbolId::mark(const char* str, uintptr_t hash) {
   147   assert(str != NULL, "invariant");
   176   assert(str != NULL, "invariant");
   148   return _cstring_table->id(str, hash);
   177   const CStringEntry& entry = _cstring_table->lookup_put(str, hash);
       
   178   if (_class_unload) {
       
   179     entry.set_unloading();
       
   180   }
       
   181   return entry.id();
   149 }
   182 }
   150 
   183 
   151 bool JfrSymbolId::is_unsafe_anonymous_klass(const Klass* k) {
   184 bool JfrSymbolId::is_unsafe_anonymous_klass(const Klass* k) {
   152   assert(k != NULL, "invariant");
   185   assert(k != NULL, "invariant");
   153   return k->is_instance_klass() && ((const InstanceKlass*)k)->is_unsafe_anonymous();
   186   return k->is_instance_klass() && ((const InstanceKlass*)k)->is_unsafe_anonymous();
   179   char hash_buf[40];
   212   char hash_buf[40];
   180   hashcode = unsafe_anonymous_klass_name_hash_code(ik);
   213   hashcode = unsafe_anonymous_klass_name_hash_code(ik);
   181   sprintf(hash_buf, "/" UINTX_FORMAT, hashcode);
   214   sprintf(hash_buf, "/" UINTX_FORMAT, hashcode);
   182   const size_t hash_len = strlen(hash_buf);
   215   const size_t hash_len = strlen(hash_buf);
   183   const size_t result_len = ik->name()->utf8_length();
   216   const size_t result_len = ik->name()->utf8_length();
   184   anonymous_symbol = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
   217   anonymous_symbol = NEW_C_HEAP_ARRAY(char, result_len + hash_len + 1, mtTracing);
       
   218   assert(anonymous_symbol != NULL, "invariant");
   185   ik->name()->as_klass_external_name(anonymous_symbol, (int)result_len + 1);
   219   ik->name()->as_klass_external_name(anonymous_symbol, (int)result_len + 1);
   186   assert(strlen(anonymous_symbol) == result_len, "invariant");
   220   assert(strlen(anonymous_symbol) == result_len, "invariant");
   187   strcpy(anonymous_symbol + result_len, hash_buf);
   221   strcpy(anonymous_symbol + result_len, hash_buf);
   188   assert(strlen(anonymous_symbol) == result_len + hash_len, "invariant");
   222   assert(strlen(anonymous_symbol) == result_len + hash_len, "invariant");
   189   return anonymous_symbol;
   223   return anonymous_symbol;
   194   const Symbol* const sym = k->name();
   228   const Symbol* const sym = k->name();
   195   assert(sym != NULL, "invariant");
   229   assert(sym != NULL, "invariant");
   196   return (uintptr_t)const_cast<Symbol*>(sym)->identity_hash();
   230   return (uintptr_t)const_cast<Symbol*>(sym)->identity_hash();
   197 }
   231 }
   198 
   232 
   199 JfrArtifactSet::JfrArtifactSet(bool current_epoch) : _symbol_id(new JfrSymbolId()),
   233 static void preload_bootstrap_loader_name(JfrSymbolId* symbol_id) {
       
   234   assert(symbol_id != NULL, "invariant");
       
   235   assert(!symbol_id->has_entries(), "invariant");
       
   236   symbol_id->mark((const char*)&BOOTSTRAP_LOADER_NAME, 0); // pre-load "bootstrap" into id 1
       
   237 }
       
   238 
       
   239 JfrArtifactSet::JfrArtifactSet(bool class_unload) : _symbol_id(new JfrSymbolId()),
   200                                                      _klass_list(NULL),
   240                                                      _klass_list(NULL),
   201                                                      _total_count(0),
   241                                                      _total_count(0) {
   202                                                      _current_epoch(current_epoch) {
   242   preload_bootstrap_loader_name(_symbol_id);
   203   initialize(current_epoch);
   243   initialize(class_unload);
   204   assert(_klass_list != NULL, "invariant");
   244   assert(_klass_list != NULL, "invariant");
   205 }
   245 }
   206 
   246 
   207 static const size_t initial_class_list_size = 200;
   247 static const size_t initial_class_list_size = 200;
   208 void JfrArtifactSet::initialize(bool current_epoch) {
   248 
       
   249 void JfrArtifactSet::initialize(bool class_unload) {
   209   assert(_symbol_id != NULL, "invariant");
   250   assert(_symbol_id != NULL, "invariant");
   210   _symbol_id->initialize();
   251   _symbol_id->set_class_unload(class_unload);
   211   assert(!_symbol_id->has_entries(), "invariant");
       
   212   _symbol_id->mark(BOOTSTRAP_LOADER_NAME, 0); // pre-load "bootstrap"
       
   213   _total_count = 0;
   252   _total_count = 0;
   214   _current_epoch = current_epoch;
       
   215   // resource allocation
   253   // resource allocation
   216   _klass_list = new GrowableArray<const Klass*>(initial_class_list_size, false, mtTracing);
   254   _klass_list = new GrowableArray<const Klass*>(initial_class_list_size, false, mtTracing);
   217 }
   255 }
   218 
   256 
   219 JfrArtifactSet::~JfrArtifactSet() {
   257 JfrArtifactSet::~JfrArtifactSet() {
   220   clear();
   258   clear();
       
   259   delete _symbol_id;
   221 }
   260 }
   222 
   261 
   223 void JfrArtifactSet::clear() {
   262 void JfrArtifactSet::clear() {
   224   _symbol_id->clear();
   263   _symbol_id->clear();
       
   264   preload_bootstrap_loader_name(_symbol_id);
   225   // _klass_list will be cleared by a ResourceMark
   265   // _klass_list will be cleared by a ResourceMark
   226 }
   266 }
   227 
   267 
   228 traceid JfrArtifactSet::mark_unsafe_anonymous_klass_name(const Klass* klass) {
   268 traceid JfrArtifactSet::mark_unsafe_anonymous_klass_name(const Klass* klass) {
   229   return _symbol_id->mark_unsafe_anonymous_klass_name(klass);
   269   return _symbol_id->mark_unsafe_anonymous_klass_name(klass);
   273 }
   313 }
   274 
   314 
   275 size_t JfrArtifactSet::total_count() const {
   315 size_t JfrArtifactSet::total_count() const {
   276   return _total_count;
   316   return _total_count;
   277 }
   317 }
   278