src/hotspot/share/classfile/stringTable.cpp
changeset 54896 ea619918de95
parent 54780 f8d182aedc92
child 54927 1512d88b24c6
equal deleted inserted replaced
54895:4f1f939d8f5d 54896:ea619918de95
    28 #include "classfile/javaClasses.inline.hpp"
    28 #include "classfile/javaClasses.inline.hpp"
    29 #include "classfile/stringTable.hpp"
    29 #include "classfile/stringTable.hpp"
    30 #include "classfile/systemDictionary.hpp"
    30 #include "classfile/systemDictionary.hpp"
    31 #include "gc/shared/collectedHeap.hpp"
    31 #include "gc/shared/collectedHeap.hpp"
    32 #include "gc/shared/oopStorage.inline.hpp"
    32 #include "gc/shared/oopStorage.inline.hpp"
    33 #include "gc/shared/oopStorageParState.inline.hpp"
       
    34 #include "logging/log.hpp"
    33 #include "logging/log.hpp"
    35 #include "logging/logStream.hpp"
    34 #include "logging/logStream.hpp"
    36 #include "memory/allocation.inline.hpp"
    35 #include "memory/allocation.inline.hpp"
    37 #include "memory/filemap.hpp"
    36 #include "memory/filemap.hpp"
    38 #include "memory/heapShared.inline.hpp"
    37 #include "memory/heapShared.inline.hpp"
    77   java_lang_String::equals
    76   java_lang_String::equals
    78 > _shared_table;
    77 > _shared_table;
    79 #endif
    78 #endif
    80 
    79 
    81 // --------------------------------------------------------------------------
    80 // --------------------------------------------------------------------------
    82 StringTable* StringTable::_the_table = NULL;
    81 
    83 volatile bool StringTable::_alt_hash = false;
    82 typedef ConcurrentHashTable<WeakHandle<vm_string_table_data>,
    84 
    83                             StringTableConfig, mtSymbol> StringTableHash;
       
    84 static StringTableHash* _local_table = NULL;
       
    85 
       
    86 volatile bool StringTable::_has_work = false;
       
    87 volatile bool StringTable::_needs_rehashing = false;
       
    88 
       
    89 volatile size_t StringTable::_uncleaned_items_count = 0;
       
    90 OopStorage* StringTable::_weak_handles = NULL;
       
    91 
       
    92 static size_t _current_size = 0;
       
    93 static volatile size_t _items_count = 0;
       
    94 
       
    95 volatile bool _alt_hash = false;
    85 static juint murmur_seed = 0;
    96 static juint murmur_seed = 0;
    86 
    97 
    87 uintx hash_string(const jchar* s, int len, bool useAlt) {
    98 uintx hash_string(const jchar* s, int len, bool useAlt) {
    88   return  useAlt ?
    99   return  useAlt ?
    89     AltHashing::murmur3_32(murmur_seed, s, len) :
   100     AltHashing::murmur3_32(murmur_seed, s, len) :
   105     ResourceMark rm(THREAD);
   116     ResourceMark rm(THREAD);
   106     // All String oops are hashed as unicode
   117     // All String oops are hashed as unicode
   107     int length;
   118     int length;
   108     jchar* chars = java_lang_String::as_unicode_string(val_oop, length, THREAD);
   119     jchar* chars = java_lang_String::as_unicode_string(val_oop, length, THREAD);
   109     if (chars != NULL) {
   120     if (chars != NULL) {
   110       return hash_string(chars, length, StringTable::_alt_hash);
   121       return hash_string(chars, length, _alt_hash);
   111     }
   122     }
   112     vm_exit_out_of_memory(length, OOM_MALLOC_ERROR, "get hash from oop");
   123     vm_exit_out_of_memory(length, OOM_MALLOC_ERROR, "get hash from oop");
   113     return 0;
   124     return 0;
   114   }
   125   }
   115   // We use default allocation/deallocation but counted
   126   // We use default allocation/deallocation but counted
   194   size_t ret;
   205   size_t ret;
   195   for (ret = 1; ((size_t)1 << ret) < val; ++ret);
   206   for (ret = 1; ((size_t)1 << ret) < val; ++ret);
   196   return ret;
   207   return ret;
   197 }
   208 }
   198 
   209 
   199 StringTable::StringTable() : _local_table(NULL), _current_size(0), _has_work(0),
   210 void StringTable::create_table() {
   200   _needs_rehashing(false), _weak_handles(NULL), _items_count(0), _uncleaned_items_count(0) {
       
   201   _weak_handles = new OopStorage("StringTable weak",
   211   _weak_handles = new OopStorage("StringTable weak",
   202                                  StringTableWeakAlloc_lock,
   212                                  StringTableWeakAlloc_lock,
   203                                  StringTableWeakActive_lock);
   213                                  StringTableWeakActive_lock);
   204   size_t start_size_log_2 = ceil_log2(StringTableSize);
   214   size_t start_size_log_2 = ceil_log2(StringTableSize);
   205   _current_size = ((size_t)1) << start_size_log_2;
   215   _current_size = ((size_t)1) << start_size_log_2;
   206   log_trace(stringtable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")",
   216   log_trace(stringtable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")",
   207                          _current_size, start_size_log_2);
   217                          _current_size, start_size_log_2);
   208   _local_table = new StringTableHash(start_size_log_2, END_SIZE, REHASH_LEN);
   218   _local_table = new StringTableHash(start_size_log_2, END_SIZE, REHASH_LEN);
   209 }
   219 }
   210 
   220 
   211 void StringTable::update_needs_rehash(bool rehash) {
       
   212   if (rehash) {
       
   213     _needs_rehashing = true;
       
   214   }
       
   215 }
       
   216 
       
   217 size_t StringTable::item_added() {
   221 size_t StringTable::item_added() {
   218   return Atomic::add((size_t)1, &(the_table()->_items_count));
   222   return Atomic::add((size_t)1, &_items_count);
   219 }
   223 }
   220 
   224 
   221 size_t StringTable::add_items_to_clean(size_t ndead) {
   225 size_t StringTable::add_items_to_clean(size_t ndead) {
   222   size_t total = Atomic::add((size_t)ndead, &(the_table()->_uncleaned_items_count));
   226   size_t total = Atomic::add((size_t)ndead, &_uncleaned_items_count);
   223   log_trace(stringtable)(
   227   log_trace(stringtable)(
   224      "Uncleaned items:" SIZE_FORMAT " added: " SIZE_FORMAT " total:" SIZE_FORMAT,
   228      "Uncleaned items:" SIZE_FORMAT " added: " SIZE_FORMAT " total:" SIZE_FORMAT,
   225      the_table()->_uncleaned_items_count, ndead, total);
   229      _uncleaned_items_count, ndead, total);
   226   return total;
   230   return total;
   227 }
   231 }
   228 
   232 
   229 void StringTable::item_removed() {
   233 void StringTable::item_removed() {
   230   Atomic::add((size_t)-1, &(the_table()->_items_count));
   234   Atomic::add((size_t)-1, &_items_count);
   231 }
   235 }
   232 
   236 
   233 double StringTable::get_load_factor() const {
   237 double StringTable::get_load_factor() {
   234   return (double)_items_count/_current_size;
   238   return (double)_items_count/_current_size;
   235 }
   239 }
   236 
   240 
   237 double StringTable::get_dead_factor() const {
   241 double StringTable::get_dead_factor() {
   238   return (double)_uncleaned_items_count/_current_size;
   242   return (double)_uncleaned_items_count/_current_size;
   239 }
   243 }
   240 
   244 
   241 size_t StringTable::table_size() {
   245 size_t StringTable::table_size() {
   242   return ((size_t)1) << _local_table->get_size_log2(Thread::current());
   246   return ((size_t)1) << _local_table->get_size_log2(Thread::current());
   243 }
   247 }
   244 
   248 
   245 void StringTable::trigger_concurrent_work() {
   249 void StringTable::trigger_concurrent_work() {
   246   MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
   250   MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
   247   the_table()->_has_work = true;
   251   _has_work = true;
   248   Service_lock->notify_all();
   252   Service_lock->notify_all();
   249 }
   253 }
   250 
   254 
   251 // Probing
   255 // Probing
   252 oop StringTable::lookup(Symbol* symbol) {
   256 oop StringTable::lookup(Symbol* symbol) {
   256   return lookup(chars, length);
   260   return lookup(chars, length);
   257 }
   261 }
   258 
   262 
   259 oop StringTable::lookup(const jchar* name, int len) {
   263 oop StringTable::lookup(const jchar* name, int len) {
   260   unsigned int hash = java_lang_String::hash_code(name, len);
   264   unsigned int hash = java_lang_String::hash_code(name, len);
   261   oop string = StringTable::the_table()->lookup_shared(name, len, hash);
   265   oop string = lookup_shared(name, len, hash);
   262   if (string != NULL) {
   266   if (string != NULL) {
   263     return string;
   267     return string;
   264   }
   268   }
   265   if (StringTable::_alt_hash) {
   269   if (_alt_hash) {
   266     hash = hash_string(name, len, true);
   270     hash = hash_string(name, len, true);
   267   }
   271   }
   268   return StringTable::the_table()->do_lookup(name, len, hash);
   272   return do_lookup(name, len, hash);
   269 }
   273 }
   270 
   274 
   271 class StringTableGet : public StackObj {
   275 class StringTableGet : public StackObj {
   272   Thread* _thread;
   276   Thread* _thread;
   273   Handle  _return;
   277   Handle  _return;
   327 }
   331 }
   328 
   332 
   329 oop StringTable::intern(Handle string_or_null_h, const jchar* name, int len, TRAPS) {
   333 oop StringTable::intern(Handle string_or_null_h, const jchar* name, int len, TRAPS) {
   330   // shared table always uses java_lang_String::hash_code
   334   // shared table always uses java_lang_String::hash_code
   331   unsigned int hash = java_lang_String::hash_code(name, len);
   335   unsigned int hash = java_lang_String::hash_code(name, len);
   332   oop found_string = StringTable::the_table()->lookup_shared(name, len, hash);
   336   oop found_string = lookup_shared(name, len, hash);
   333   if (found_string != NULL) {
   337   if (found_string != NULL) {
   334     return found_string;
   338     return found_string;
   335   }
   339   }
   336   if (StringTable::_alt_hash) {
   340   if (_alt_hash) {
   337     hash = hash_string(name, len, true);
   341     hash = hash_string(name, len, true);
   338   }
   342   }
   339   found_string = StringTable::the_table()->do_lookup(name, len, hash);
   343   found_string = do_lookup(name, len, hash);
   340   if (found_string != NULL) {
   344   if (found_string != NULL) {
   341     return found_string;
   345     return found_string;
   342   }
   346   }
   343   return StringTable::the_table()->do_intern(string_or_null_h, name, len,
   347   return do_intern(string_or_null_h, name, len, hash, CHECK_NULL);
   344                                              hash, CHECK_NULL);
       
   345 }
   348 }
   346 
   349 
   347 oop StringTable::do_intern(Handle string_or_null_h, const jchar* name,
   350 oop StringTable::do_intern(Handle string_or_null_h, const jchar* name,
   348                            int len, uintx hash, TRAPS) {
   351                            int len, uintx hash, TRAPS) {
   349   HandleMark hm(THREAD);  // cleanup strings created
   352   HandleMark hm(THREAD);  // cleanup strings created
   382   } while(true);
   385   } while(true);
   383 }
   386 }
   384 
   387 
   385 void StringTable::oops_do(OopClosure* f) {
   388 void StringTable::oops_do(OopClosure* f) {
   386   assert(f != NULL, "No closure");
   389   assert(f != NULL, "No closure");
   387   StringTable::the_table()->_weak_handles->oops_do(f);
   390   _weak_handles->oops_do(f);
   388 }
       
   389 
       
   390 void StringTable::possibly_parallel_oops_do(
       
   391    OopStorage::ParState<false /* concurrent */, false /* const */>*
       
   392    _par_state_string, OopClosure* f)
       
   393 {
       
   394   assert(f != NULL, "No closure");
       
   395   _par_state_string->oops_do(f);
       
   396 }
   391 }
   397 
   392 
   398 // Concurrent work
   393 // Concurrent work
   399 void StringTable::grow(JavaThread* jt) {
   394 void StringTable::grow(JavaThread* jt) {
   400   StringTableHash::GrowTask gt(_local_table);
   395   StringTableHash::GrowTask gt(_local_table);
   478                            load_factor, dead_factor);
   473                            load_factor, dead_factor);
   479     trigger_concurrent_work();
   474     trigger_concurrent_work();
   480   }
   475   }
   481 }
   476 }
   482 
   477 
   483 void StringTable::concurrent_work(JavaThread* jt) {
   478 void StringTable::do_concurrent_work(JavaThread* jt) {
   484   _has_work = false;
   479   _has_work = false;
   485   double load_factor = get_load_factor();
   480   double load_factor = get_load_factor();
   486   log_debug(stringtable, perf)("Concurrent work, live factor: %g", load_factor);
   481   log_debug(stringtable, perf)("Concurrent work, live factor: %g", load_factor);
   487   // We prefer growing, since that also removes dead items
   482   // We prefer growing, since that also removes dead items
   488   if (load_factor > PREF_AVG_LIST_LEN && !_local_table->is_max_size_reached()) {
   483   if (load_factor > PREF_AVG_LIST_LEN && !_local_table->is_max_size_reached()) {
   490   } else {
   485   } else {
   491     clean_dead_entries(jt);
   486     clean_dead_entries(jt);
   492   }
   487   }
   493 }
   488 }
   494 
   489 
   495 void StringTable::do_concurrent_work(JavaThread* jt) {
       
   496   StringTable::the_table()->concurrent_work(jt);
       
   497 }
       
   498 
       
   499 // Rehash
   490 // Rehash
   500 bool StringTable::do_rehash() {
   491 bool StringTable::do_rehash() {
   501   if (!_local_table->is_safepoint_safe()) {
   492   if (!_local_table->is_safepoint_safe()) {
   502     return false;
   493     return false;
   503   }
   494   }
   517   _local_table = new_table;
   508   _local_table = new_table;
   518 
   509 
   519   return true;
   510   return true;
   520 }
   511 }
   521 
   512 
   522 void StringTable::try_rehash_table() {
   513 void StringTable::rehash_table() {
   523   static bool rehashed = false;
   514   static bool rehashed = false;
   524   log_debug(stringtable)("Table imbalanced, rehashing called.");
   515   log_debug(stringtable)("Table imbalanced, rehashing called.");
   525 
   516 
   526   // Grow instead of rehash.
   517   // Grow instead of rehash.
   527   if (get_load_factor() > PREF_AVG_LIST_LEN &&
   518   if (get_load_factor() > PREF_AVG_LIST_LEN &&
   546     } else {
   537     } else {
   547       log_info(stringtable)("Resizes in progress rehashing skipped.");
   538       log_info(stringtable)("Resizes in progress rehashing skipped.");
   548     }
   539     }
   549   }
   540   }
   550   _needs_rehashing = false;
   541   _needs_rehashing = false;
   551 }
       
   552 
       
   553 void StringTable::rehash_table() {
       
   554   StringTable::the_table()->try_rehash_table();
       
   555 }
   542 }
   556 
   543 
   557 // Statistics
   544 // Statistics
   558 static int literal_size(oop obj) {
   545 static int literal_size(oop obj) {
   559   // NOTE: this would over-count if (pre-JDK8)
   546   // NOTE: this would over-count if (pre-JDK8)
   607 
   594 
   608 // This verification is part of Universe::verify() and needs to be quick.
   595 // This verification is part of Universe::verify() and needs to be quick.
   609 void StringTable::verify() {
   596 void StringTable::verify() {
   610   Thread* thr = Thread::current();
   597   Thread* thr = Thread::current();
   611   VerifyStrings vs;
   598   VerifyStrings vs;
   612   if (!the_table()->_local_table->try_scan(thr, vs)) {
   599   if (!_local_table->try_scan(thr, vs)) {
   613     log_info(stringtable)("verify unavailable at this moment");
   600     log_info(stringtable)("verify unavailable at this moment");
   614   }
   601   }
   615 }
   602 }
   616 
   603 
   617 // Verification and comp
   604 // Verification and comp
   640 
   627 
   641 size_t StringTable::verify_and_compare_entries() {
   628 size_t StringTable::verify_and_compare_entries() {
   642   Thread* thr = Thread::current();
   629   Thread* thr = Thread::current();
   643   GrowableArray<oop>* oops =
   630   GrowableArray<oop>* oops =
   644     new (ResourceObj::C_HEAP, mtInternal)
   631     new (ResourceObj::C_HEAP, mtInternal)
   645       GrowableArray<oop>((int)the_table()->_current_size, true);
   632       GrowableArray<oop>((int)_current_size, true);
   646 
   633 
   647   VerifyCompStrings vcs(oops);
   634   VerifyCompStrings vcs(oops);
   648   if (!the_table()->_local_table->try_scan(thr, vcs)) {
   635   if (!_local_table->try_scan(thr, vcs)) {
   649     log_info(stringtable)("verify unavailable at this moment");
   636     log_info(stringtable)("verify unavailable at this moment");
   650   }
   637   }
   651   delete oops;
   638   delete oops;
   652   return vcs._errors;
   639   return vcs._errors;
   653 }
   640 }
   690   };
   677   };
   691 };
   678 };
   692 
   679 
   693 void StringTable::dump(outputStream* st, bool verbose) {
   680 void StringTable::dump(outputStream* st, bool verbose) {
   694   if (!verbose) {
   681   if (!verbose) {
   695     the_table()->print_table_statistics(st, "StringTable");
   682     print_table_statistics(st, "StringTable");
   696   } else {
   683   } else {
   697     Thread* thr = Thread::current();
   684     Thread* thr = Thread::current();
   698     ResourceMark rm(thr);
   685     ResourceMark rm(thr);
   699     st->print_cr("VERSION: 1.1");
   686     st->print_cr("VERSION: 1.1");
   700     PrintString ps(thr, st);
   687     PrintString ps(thr, st);
   701     if (!the_table()->_local_table->try_scan(thr, ps)) {
   688     if (!_local_table->try_scan(thr, ps)) {
   702       st->print_cr("dump unavailable at this moment");
   689       st->print_cr("dump unavailable at this moment");
   703     }
   690     }
   704   }
   691   }
   705 }
   692 }
   706 
   693 
   783 
   770 
   784 void StringTable::copy_shared_string_table(CompactHashtableWriter* writer) {
   771 void StringTable::copy_shared_string_table(CompactHashtableWriter* writer) {
   785   assert(HeapShared::is_heap_object_archiving_allowed(), "must be");
   772   assert(HeapShared::is_heap_object_archiving_allowed(), "must be");
   786 
   773 
   787   CopyToArchive copy(writer);
   774   CopyToArchive copy(writer);
   788   StringTable::the_table()->_local_table->do_safepoint_scan(copy);
   775   _local_table->do_safepoint_scan(copy);
   789 }
   776 }
   790 
   777 
   791 void StringTable::write_to_archive() {
   778 void StringTable::write_to_archive() {
   792   assert(HeapShared::is_heap_object_archiving_allowed(), "must be");
   779   assert(HeapShared::is_heap_object_archiving_allowed(), "must be");
   793 
   780 
   794   _shared_table.reset();
   781   _shared_table.reset();
   795   int num_buckets = CompactHashtableWriter::default_num_buckets(
   782   int num_buckets = CompactHashtableWriter::default_num_buckets(_items_count);
   796       StringTable::the_table()->_items_count);
       
   797   CompactHashtableWriter writer(num_buckets,
   783   CompactHashtableWriter writer(num_buckets,
   798                                 &MetaspaceShared::stats()->string);
   784                                 &MetaspaceShared::stats()->string);
   799 
   785 
   800   // Copy the interned strings into the "string space" within the java heap
   786   // Copy the interned strings into the "string space" within the java heap
   801   copy_shared_string_table(&writer);
   787   copy_shared_string_table(&writer);