# HG changeset patch # User coleenp # Date 1558004957 14400 # Node ID ea619918de9592873491ac7f2b96d2fa8c86e03a # Parent 4f1f939d8f5de131410764f9f7ca72eb4a73c54b 8223956: Make SymbolTable and StringTable AllStatic Summary: Removed superfluous and confusing _the_table pointer. Reviewed-by: gziemski, rehn diff -r 4f1f939d8f5d -r ea619918de95 src/hotspot/share/classfile/stringTable.cpp --- a/src/hotspot/share/classfile/stringTable.cpp Thu May 16 16:40:48 2019 +0530 +++ b/src/hotspot/share/classfile/stringTable.cpp Thu May 16 07:09:17 2019 -0400 @@ -30,7 +30,6 @@ #include "classfile/systemDictionary.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/oopStorage.inline.hpp" -#include "gc/shared/oopStorageParState.inline.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/allocation.inline.hpp" @@ -79,9 +78,21 @@ #endif // -------------------------------------------------------------------------- -StringTable* StringTable::_the_table = NULL; -volatile bool StringTable::_alt_hash = false; + +typedef ConcurrentHashTable, + StringTableConfig, mtSymbol> StringTableHash; +static StringTableHash* _local_table = NULL; + +volatile bool StringTable::_has_work = false; +volatile bool StringTable::_needs_rehashing = false; +volatile size_t StringTable::_uncleaned_items_count = 0; +OopStorage* StringTable::_weak_handles = NULL; + +static size_t _current_size = 0; +static volatile size_t _items_count = 0; + +volatile bool _alt_hash = false; static juint murmur_seed = 0; uintx hash_string(const jchar* s, int len, bool useAlt) { @@ -107,7 +118,7 @@ int length; jchar* chars = java_lang_String::as_unicode_string(val_oop, length, THREAD); if (chars != NULL) { - return hash_string(chars, length, StringTable::_alt_hash); + return hash_string(chars, length, _alt_hash); } vm_exit_out_of_memory(length, OOM_MALLOC_ERROR, "get hash from oop"); return 0; @@ -196,8 +207,7 @@ return ret; } -StringTable::StringTable() : _local_table(NULL), _current_size(0), _has_work(0), - _needs_rehashing(false), _weak_handles(NULL), _items_count(0), _uncleaned_items_count(0) { +void StringTable::create_table() { _weak_handles = new OopStorage("StringTable weak", StringTableWeakAlloc_lock, StringTableWeakActive_lock); @@ -208,33 +218,27 @@ _local_table = new StringTableHash(start_size_log_2, END_SIZE, REHASH_LEN); } -void StringTable::update_needs_rehash(bool rehash) { - if (rehash) { - _needs_rehashing = true; - } -} - size_t StringTable::item_added() { - return Atomic::add((size_t)1, &(the_table()->_items_count)); + return Atomic::add((size_t)1, &_items_count); } size_t StringTable::add_items_to_clean(size_t ndead) { - size_t total = Atomic::add((size_t)ndead, &(the_table()->_uncleaned_items_count)); + size_t total = Atomic::add((size_t)ndead, &_uncleaned_items_count); log_trace(stringtable)( "Uncleaned items:" SIZE_FORMAT " added: " SIZE_FORMAT " total:" SIZE_FORMAT, - the_table()->_uncleaned_items_count, ndead, total); + _uncleaned_items_count, ndead, total); return total; } void StringTable::item_removed() { - Atomic::add((size_t)-1, &(the_table()->_items_count)); + Atomic::add((size_t)-1, &_items_count); } -double StringTable::get_load_factor() const { +double StringTable::get_load_factor() { return (double)_items_count/_current_size; } -double StringTable::get_dead_factor() const { +double StringTable::get_dead_factor() { return (double)_uncleaned_items_count/_current_size; } @@ -244,7 +248,7 @@ void StringTable::trigger_concurrent_work() { MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag); - the_table()->_has_work = true; + _has_work = true; Service_lock->notify_all(); } @@ -258,14 +262,14 @@ oop StringTable::lookup(const jchar* name, int len) { unsigned int hash = java_lang_String::hash_code(name, len); - oop string = StringTable::the_table()->lookup_shared(name, len, hash); + oop string = lookup_shared(name, len, hash); if (string != NULL) { return string; } - if (StringTable::_alt_hash) { + if (_alt_hash) { hash = hash_string(name, len, true); } - return StringTable::the_table()->do_lookup(name, len, hash); + return do_lookup(name, len, hash); } class StringTableGet : public StackObj { @@ -329,19 +333,18 @@ oop StringTable::intern(Handle string_or_null_h, const jchar* name, int len, TRAPS) { // shared table always uses java_lang_String::hash_code unsigned int hash = java_lang_String::hash_code(name, len); - oop found_string = StringTable::the_table()->lookup_shared(name, len, hash); + oop found_string = lookup_shared(name, len, hash); if (found_string != NULL) { return found_string; } - if (StringTable::_alt_hash) { + if (_alt_hash) { hash = hash_string(name, len, true); } - found_string = StringTable::the_table()->do_lookup(name, len, hash); + found_string = do_lookup(name, len, hash); if (found_string != NULL) { return found_string; } - return StringTable::the_table()->do_intern(string_or_null_h, name, len, - hash, CHECK_NULL); + return do_intern(string_or_null_h, name, len, hash, CHECK_NULL); } oop StringTable::do_intern(Handle string_or_null_h, const jchar* name, @@ -384,15 +387,7 @@ void StringTable::oops_do(OopClosure* f) { assert(f != NULL, "No closure"); - StringTable::the_table()->_weak_handles->oops_do(f); -} - -void StringTable::possibly_parallel_oops_do( - OopStorage::ParState* - _par_state_string, OopClosure* f) -{ - assert(f != NULL, "No closure"); - _par_state_string->oops_do(f); + _weak_handles->oops_do(f); } // Concurrent work @@ -480,7 +475,7 @@ } } -void StringTable::concurrent_work(JavaThread* jt) { +void StringTable::do_concurrent_work(JavaThread* jt) { _has_work = false; double load_factor = get_load_factor(); log_debug(stringtable, perf)("Concurrent work, live factor: %g", load_factor); @@ -492,10 +487,6 @@ } } -void StringTable::do_concurrent_work(JavaThread* jt) { - StringTable::the_table()->concurrent_work(jt); -} - // Rehash bool StringTable::do_rehash() { if (!_local_table->is_safepoint_safe()) { @@ -519,7 +510,7 @@ return true; } -void StringTable::try_rehash_table() { +void StringTable::rehash_table() { static bool rehashed = false; log_debug(stringtable)("Table imbalanced, rehashing called."); @@ -550,10 +541,6 @@ _needs_rehashing = false; } -void StringTable::rehash_table() { - StringTable::the_table()->try_rehash_table(); -} - // Statistics static int literal_size(oop obj) { // NOTE: this would over-count if (pre-JDK8) @@ -609,7 +596,7 @@ void StringTable::verify() { Thread* thr = Thread::current(); VerifyStrings vs; - if (!the_table()->_local_table->try_scan(thr, vs)) { + if (!_local_table->try_scan(thr, vs)) { log_info(stringtable)("verify unavailable at this moment"); } } @@ -642,10 +629,10 @@ Thread* thr = Thread::current(); GrowableArray* oops = new (ResourceObj::C_HEAP, mtInternal) - GrowableArray((int)the_table()->_current_size, true); + GrowableArray((int)_current_size, true); VerifyCompStrings vcs(oops); - if (!the_table()->_local_table->try_scan(thr, vcs)) { + if (!_local_table->try_scan(thr, vcs)) { log_info(stringtable)("verify unavailable at this moment"); } delete oops; @@ -692,13 +679,13 @@ void StringTable::dump(outputStream* st, bool verbose) { if (!verbose) { - the_table()->print_table_statistics(st, "StringTable"); + print_table_statistics(st, "StringTable"); } else { Thread* thr = Thread::current(); ResourceMark rm(thr); st->print_cr("VERSION: 1.1"); PrintString ps(thr, st); - if (!the_table()->_local_table->try_scan(thr, ps)) { + if (!_local_table->try_scan(thr, ps)) { st->print_cr("dump unavailable at this moment"); } } @@ -785,15 +772,14 @@ assert(HeapShared::is_heap_object_archiving_allowed(), "must be"); CopyToArchive copy(writer); - StringTable::the_table()->_local_table->do_safepoint_scan(copy); + _local_table->do_safepoint_scan(copy); } void StringTable::write_to_archive() { assert(HeapShared::is_heap_object_archiving_allowed(), "must be"); _shared_table.reset(); - int num_buckets = CompactHashtableWriter::default_num_buckets( - StringTable::the_table()->_items_count); + int num_buckets = CompactHashtableWriter::default_num_buckets(_items_count); CompactHashtableWriter writer(num_buckets, &MetaspaceShared::stats()->string); diff -r 4f1f939d8f5d -r ea619918de95 src/hotspot/share/classfile/stringTable.hpp --- a/src/hotspot/share/classfile/stringTable.hpp Thu May 16 16:40:48 2019 +0530 +++ b/src/hotspot/share/classfile/stringTable.hpp Thu May 16 07:09:17 2019 -0400 @@ -26,21 +26,17 @@ #define SHARE_CLASSFILE_STRINGTABLE_HPP #include "gc/shared/oopStorage.hpp" -#include "gc/shared/oopStorageParState.hpp" #include "memory/allocation.hpp" #include "memory/padded.hpp" #include "oops/oop.hpp" #include "oops/weakHandle.hpp" -#include "utilities/concurrentHashTable.hpp" +#include "utilities/tableStatistics.hpp" class CompactHashtableWriter; class SerializeClosure; class StringTable; class StringTableConfig; -typedef ConcurrentHashTable, - StringTableConfig, mtSymbol> StringTableHash; - class StringTableCreateEntry; class StringTable : public CHeapObj{ @@ -49,94 +45,64 @@ friend class StringTableConfig; friend class StringTableCreateEntry; -private: - void grow(JavaThread* jt); - void clean_dead_entries(JavaThread* jt); + static volatile bool _has_work; + static volatile size_t _uncleaned_items_count; - // The string table - static StringTable* _the_table; - static volatile bool _alt_hash; - -private: - - StringTableHash* _local_table; - size_t _current_size; - volatile bool _has_work; // Set if one bucket is out of balance due to hash algorithm deficiency - volatile bool _needs_rehashing; + static volatile bool _needs_rehashing; - OopStorage* _weak_handles; + static OopStorage* _weak_handles; - volatile size_t _items_count; - DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile size_t)); - volatile size_t _uncleaned_items_count; - DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile size_t)); + static void grow(JavaThread* jt); + static void clean_dead_entries(JavaThread* jt); - double get_load_factor() const; - double get_dead_factor() const; + static double get_load_factor(); + static double get_dead_factor(); - void check_concurrent_work(); - void trigger_concurrent_work(); + static void check_concurrent_work(); + static void trigger_concurrent_work(); static size_t item_added(); static void item_removed(); - size_t add_items_to_clean(size_t ndead); - - StringTable(); + static size_t add_items_to_clean(size_t ndead); static oop intern(Handle string_or_null_h, const jchar* name, int len, TRAPS); - oop do_intern(Handle string_or_null, const jchar* name, int len, uintx hash, TRAPS); - oop do_lookup(const jchar* name, int len, uintx hash); + static oop do_intern(Handle string_or_null, const jchar* name, int len, uintx hash, TRAPS); + static oop do_lookup(const jchar* name, int len, uintx hash); - void concurrent_work(JavaThread* jt); - void print_table_statistics(outputStream* st, const char* table_name); + static void print_table_statistics(outputStream* st, const char* table_name); - void try_rehash_table(); - bool do_rehash(); - inline void update_needs_rehash(bool rehash); + static bool do_rehash(); public: - // The string table - static StringTable* the_table() { return _the_table; } - size_t table_size(); - TableStatistics get_table_statistics(); + static size_t table_size(); + static TableStatistics get_table_statistics(); - static OopStorage* weak_storage() { return the_table()->_weak_handles; } + static OopStorage* weak_storage() { return _weak_handles; } - static void create_table() { - assert(_the_table == NULL, "One string table allowed."); - _the_table = new StringTable(); - } + static void create_table(); static void do_concurrent_work(JavaThread* jt); - static bool has_work() { return the_table()->_has_work; } + static bool has_work() { return _has_work; } // GC support // Must be called before a parallel walk where strings might die. - static void reset_dead_counter() { - the_table()->_uncleaned_items_count = 0; - } + static void reset_dead_counter() { _uncleaned_items_count = 0; } + // After the parallel walk this method must be called to trigger // cleaning. Note it might trigger a resize instead. - static void finish_dead_counter() { - the_table()->check_concurrent_work(); - } + static void finish_dead_counter() { check_concurrent_work(); } // If GC uses ParState directly it should add the number of cleared // strings to this method. - static void inc_dead_counter(size_t ndead) { - the_table()->add_items_to_clean(ndead); - } + static void inc_dead_counter(size_t ndead) { add_items_to_clean(ndead); } // Serially invoke "f->do_oop" on the locations of all oops in the table. + // Used by JFR leak profiler. TODO: it should find these oops through + // the WeakProcessor. static void oops_do(OopClosure* f); - // Possibly parallel versions of the above - static void possibly_parallel_oops_do( - OopStorage::ParState* par_state_string, - OopClosure* f); - // Probing static oop lookup(Symbol* symbol); static oop lookup(const jchar* chars, int length); @@ -148,12 +114,16 @@ // Rehash the string table if it gets out of balance static void rehash_table(); - static bool needs_rehashing() - { return StringTable::the_table()->_needs_rehashing; } + static bool needs_rehashing() { return _needs_rehashing; } + static inline void update_needs_rehash(bool rehash) { + if (rehash) { + _needs_rehashing = true; + } + } // Sharing private: - oop lookup_shared(const jchar* name, int len, unsigned int hash) NOT_CDS_JAVA_HEAP_RETURN_(NULL); + static oop lookup_shared(const jchar* name, int len, unsigned int hash) NOT_CDS_JAVA_HEAP_RETURN_(NULL); static void copy_shared_string_table(CompactHashtableWriter* ch_table) NOT_CDS_JAVA_HEAP_RETURN; public: static oop create_archived_string(oop s, Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN_(NULL); diff -r 4f1f939d8f5d -r ea619918de95 src/hotspot/share/classfile/symbolTable.cpp --- a/src/hotspot/share/classfile/symbolTable.cpp Thu May 16 16:40:48 2019 +0530 +++ b/src/hotspot/share/classfile/symbolTable.cpp Thu May 16 07:09:17 2019 -0400 @@ -70,9 +70,26 @@ > _shared_table; // -------------------------------------------------------------------------- -SymbolTable* SymbolTable::_the_table = NULL; -volatile bool SymbolTable::_alt_hash = false; -volatile bool SymbolTable::_lookup_shared_first = false; + +typedef ConcurrentHashTable SymbolTableHash; +static SymbolTableHash* _local_table = NULL; + +volatile bool SymbolTable::_has_work = 0; +volatile bool SymbolTable::_needs_rehashing = false; + +// For statistics +static size_t _symbols_removed = 0; +static size_t _symbols_counted = 0; +static size_t _current_size = 0; + +static volatile size_t _items_count = 0; +static volatile bool _has_items_to_clean = false; + + +static volatile bool _alt_hash = false; +static volatile bool _lookup_shared_first = false; + // Static arena for symbols that are not deallocated Arena* SymbolTable::_arena = NULL; @@ -104,7 +121,7 @@ if (*is_dead) { return 0; } else { - return hash_symbol((const char*)value->bytes(), value->utf8_length(), SymbolTable::_alt_hash); + return hash_symbol((const char*)value->bytes(), value->utf8_length(), _alt_hash); } } // We use default allocation/deallocation but counted @@ -136,16 +153,19 @@ return ret; } -SymbolTable::SymbolTable() : - _symbols_removed(0), _symbols_counted(0), _local_table(NULL), - _current_size(0), _has_work(0), _needs_rehashing(false), - _items_count(0), _has_items_to_clean(false) { - +void SymbolTable::create_table () { size_t start_size_log_2 = ceil_log2(SymbolTableSize); _current_size = ((size_t)1) << start_size_log_2; log_trace(symboltable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")", _current_size, start_size_log_2); _local_table = new SymbolTableHash(start_size_log_2, END_SIZE, REHASH_LEN); + + // Initialize the arena for global symbols, size passed in depends on CDS. + if (symbol_alloc_arena_size == 0) { + _arena = new (mtSymbol) Arena(mtSymbol); + } else { + _arena = new (mtSymbol) Arena(mtSymbol, symbol_alloc_arena_size); + } } void SymbolTable::delete_symbol(Symbol* sym) { @@ -162,26 +182,20 @@ } } -void SymbolTable::update_needs_rehash(bool rehash) { - if (rehash) { - _needs_rehashing = true; - } -} - void SymbolTable::reset_has_items_to_clean() { Atomic::store(false, &_has_items_to_clean); } void SymbolTable::mark_has_items_to_clean() { Atomic::store(true, &_has_items_to_clean); } -bool SymbolTable::has_items_to_clean() const { return Atomic::load(&_has_items_to_clean); } +bool SymbolTable::has_items_to_clean() { return Atomic::load(&_has_items_to_clean); } void SymbolTable::item_added() { - Atomic::inc(&(SymbolTable::the_table()->_items_count)); + Atomic::inc(&_items_count); } void SymbolTable::item_removed() { - Atomic::inc(&(SymbolTable::the_table()->_symbols_removed)); - Atomic::dec(&(SymbolTable::the_table()->_items_count)); + Atomic::inc(&(_symbols_removed)); + Atomic::dec(&_items_count); } -double SymbolTable::get_load_factor() const { +double SymbolTable::get_load_factor() { return (double)_items_count/_current_size; } @@ -191,7 +205,7 @@ void SymbolTable::trigger_cleanup() { MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag); - SymbolTable::the_table()->_has_work = true; + _has_work = true; Service_lock->notify_all(); } @@ -214,15 +228,6 @@ return sym; } -void SymbolTable::initialize_symbols(int arena_alloc_size) { - // Initialize the arena for global symbols, size passed in depends on CDS. - if (arena_alloc_size == 0) { - _arena = new (mtSymbol) Arena(mtSymbol); - } else { - _arena = new (mtSymbol) Arena(mtSymbol, arena_alloc_size); - } -} - class SymbolsDo : StackObj { SymbolClosure *_cl; public: @@ -252,7 +257,7 @@ // all symbols from the dynamic table SymbolsDo sd(cl); - if (!SymbolTable::the_table()->_local_table->try_scan(Thread::current(), sd)) { + if (!_local_table->try_scan(Thread::current(), sd)) { log_info(stringtable)("symbols_do unavailable at this moment"); } } @@ -272,12 +277,12 @@ void SymbolTable::metaspace_pointers_do(MetaspaceClosure* it) { assert(DumpSharedSpaces, "called only during dump time"); MetaspacePointersDo mpd(it); - SymbolTable::the_table()->_local_table->do_safepoint_scan(mpd); + _local_table->do_safepoint_scan(mpd); } Symbol* SymbolTable::lookup_dynamic(const char* name, int len, unsigned int hash) { - Symbol* sym = SymbolTable::the_table()->do_lookup(name, len, hash); + Symbol* sym = do_lookup(name, len, hash); assert((sym == NULL) || sym->refcount() != 0, "refcount must not be zero"); return sym; } @@ -285,7 +290,7 @@ Symbol* SymbolTable::lookup_shared(const char* name, int len, unsigned int hash) { if (!_shared_table.empty()) { - if (SymbolTable::_alt_hash) { + if (_alt_hash) { // hash_code parameter may use alternate hashing algorithm but the shared table // always uses the same original hash code. hash = hash_shared_symbol(name, len); @@ -318,10 +323,10 @@ } Symbol* SymbolTable::new_symbol(const char* name, int len) { - unsigned int hash = hash_symbol(name, len, SymbolTable::_alt_hash); - Symbol* sym = SymbolTable::the_table()->lookup_common(name, len, hash); + unsigned int hash = hash_symbol(name, len, _alt_hash); + Symbol* sym = lookup_common(name, len, hash); if (sym == NULL) { - sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, true); + sym = do_add_if_needed(name, len, hash, true); } assert(sym->refcount() != 0, "lookup should have incremented the count"); assert(sym->equals(name, len), "symbol must be properly initialized"); @@ -333,10 +338,10 @@ assert(sym->refcount() != 0, "require a valid symbol"); const char* name = (const char*)sym->base() + begin; int len = end - begin; - unsigned int hash = hash_symbol(name, len, SymbolTable::_alt_hash); - Symbol* found = SymbolTable::the_table()->lookup_common(name, len, hash); + unsigned int hash = hash_symbol(name, len, _alt_hash); + Symbol* found = lookup_common(name, len, hash); if (found == NULL) { - found = SymbolTable::the_table()->do_add_if_needed(name, len, hash, true); + found = do_add_if_needed(name, len, hash, true); } return found; } @@ -400,8 +405,8 @@ } Symbol* SymbolTable::lookup_only(const char* name, int len, unsigned int& hash) { - hash = hash_symbol(name, len, SymbolTable::_alt_hash); - return SymbolTable::the_table()->lookup_common(name, len, hash); + hash = hash_symbol(name, len, _alt_hash); + return lookup_common(name, len, hash); } // Suggestion: Push unicode-based lookup all the way into the hashing @@ -446,8 +451,8 @@ const char *name = names[i]; int len = lengths[i]; unsigned int hash = hashValues[i]; - assert(SymbolTable::the_table()->lookup_shared(name, len, hash) == NULL, "must have checked already"); - Symbol* sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, c_heap); + assert(lookup_shared(name, len, hash) == NULL, "must have checked already"); + Symbol* sym = do_add_if_needed(name, len, hash, c_heap); assert(sym->refcount() != 0, "lookup should have incremented the count"); cp->symbol_at_put(cp_indices[i], sym); } @@ -466,7 +471,7 @@ sym = stg.get_res_sym(); break; } - sym = SymbolTable::the_table()->allocate_symbol(name, len, heap); + sym = allocate_symbol(name, len, heap); if (_local_table->insert(THREAD, lookup, sym, &rehash_warning, &clean_hint)) { break; } @@ -488,7 +493,7 @@ int len = (int)strlen(name); Symbol* sym = SymbolTable::lookup_only(name, len, hash); if (sym == NULL) { - sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, false); + sym = do_add_if_needed(name, len, hash, false); } if (!sym->is_permanent()) { sym->make_permanent(); @@ -534,7 +539,7 @@ void SymbolTable::verify() { Thread* thr = Thread::current(); VerifySymbols vs; - if (!SymbolTable::the_table()->_local_table->try_scan(thr, vs)) { + if (!_local_table->try_scan(thr, vs)) { log_info(stringtable)("verify unavailable at this moment"); } } @@ -560,13 +565,13 @@ void SymbolTable::dump(outputStream* st, bool verbose) { if (!verbose) { - SymbolTable::the_table()->print_table_statistics(st, "SymbolTable"); + print_table_statistics(st, "SymbolTable"); } else { Thread* thr = Thread::current(); ResourceMark rm(thr); st->print_cr("VERSION: 1.1"); DumpSymbol ds(thr, st); - if (!SymbolTable::the_table()->_local_table->try_scan(thr, ds)) { + if (!_local_table->try_scan(thr, ds)) { log_info(symboltable)("dump unavailable at this moment"); } } @@ -590,14 +595,14 @@ void SymbolTable::copy_shared_symbol_table(CompactHashtableWriter* writer) { CopyToArchive copy(writer); - SymbolTable::the_table()->_local_table->do_safepoint_scan(copy); + _local_table->do_safepoint_scan(copy); } void SymbolTable::write_to_archive() { _shared_table.reset(); int num_buckets = CompactHashtableWriter::default_num_buckets( - SymbolTable::the_table()->_items_count); + _items_count); CompactHashtableWriter writer(num_buckets, &MetaspaceShared::stats()->symbol); copy_shared_symbol_table(&writer); @@ -607,7 +612,7 @@ Symbol* sym = vmSymbols::java_lang_Object(); const char* name = (const char*)sym->bytes(); int len = sym->utf8_length(); - unsigned int hash = hash_symbol(name, len, SymbolTable::_alt_hash); + unsigned int hash = hash_symbol(name, len, _alt_hash); assert(sym == _shared_table.lookup(name, hash, len), "sanity"); } @@ -684,7 +689,7 @@ } bdt.cont(jt); } - SymbolTable::the_table()->reset_has_items_to_clean(); + reset_has_items_to_clean(); bdt.done(jt); } @@ -708,7 +713,7 @@ } } -void SymbolTable::concurrent_work(JavaThread* jt) { +void SymbolTable::do_concurrent_work(JavaThread* jt) { double load_factor = get_load_factor(); log_debug(symboltable, perf)("Concurrent work, live factor: %g", load_factor); // We prefer growing, since that also removes dead items @@ -720,10 +725,6 @@ _has_work = false; } -void SymbolTable::do_concurrent_work(JavaThread* jt) { - SymbolTable::the_table()->concurrent_work(jt); -} - // Rehash bool SymbolTable::do_rehash() { if (!_local_table->is_safepoint_safe()) { @@ -747,7 +748,7 @@ return true; } -void SymbolTable::try_rehash_table() { +void SymbolTable::rehash_table() { static bool rehashed = false; log_debug(symboltable)("Table imbalanced, rehashing called."); @@ -779,10 +780,6 @@ _needs_rehashing = false; } -void SymbolTable::rehash_table() { - SymbolTable::the_table()->try_rehash_table(); -} - //--------------------------------------------------------------------------- // Non-product code @@ -830,18 +827,17 @@ }; void SymbolTable::print_histogram() { - SymbolTable* st = SymbolTable::the_table(); HistogramIterator hi; - st->_local_table->do_scan(Thread::current(), hi); + _local_table->do_scan(Thread::current(), hi); tty->print_cr("Symbol Table Histogram:"); tty->print_cr(" Total number of symbols " SIZE_FORMAT_W(7), hi.total_count); tty->print_cr(" Total size in memory " SIZE_FORMAT_W(7) "K", (hi.total_size * wordSize) / 1024); - tty->print_cr(" Total counted " SIZE_FORMAT_W(7), st->_symbols_counted); - tty->print_cr(" Total removed " SIZE_FORMAT_W(7), st->_symbols_removed); - if (SymbolTable::the_table()->_symbols_counted > 0) { + tty->print_cr(" Total counted " SIZE_FORMAT_W(7), _symbols_counted); + tty->print_cr(" Total removed " SIZE_FORMAT_W(7), _symbols_removed); + if (_symbols_counted > 0) { tty->print_cr(" Percent removed %3.2f", - ((float)st->_symbols_removed / st->_symbols_counted) * 100); + ((float)_symbols_removed / _symbols_counted) * 100); } tty->print_cr(" Reference counts " SIZE_FORMAT_W(7), Symbol::_total_count); tty->print_cr(" Symbol arena used " SIZE_FORMAT_W(7) "K", arena()->used() / 1024); diff -r 4f1f939d8f5d -r ea619918de95 src/hotspot/share/classfile/symbolTable.hpp --- a/src/hotspot/share/classfile/symbolTable.hpp Thu May 16 16:40:48 2019 +0530 +++ b/src/hotspot/share/classfile/symbolTable.hpp Thu May 16 07:09:17 2019 -0400 @@ -28,8 +28,7 @@ #include "memory/allocation.hpp" #include "memory/padded.hpp" #include "oops/symbol.hpp" -#include "utilities/concurrentHashTable.hpp" -#include "utilities/hashtable.hpp" +#include "utilities/tableStatistics.hpp" class JavaThread; @@ -90,58 +89,43 @@ class SerializeClosure; class SymbolTableConfig; -typedef ConcurrentHashTable SymbolTableHash; - class SymbolTableCreateEntry; -class SymbolTable : public CHeapObj { +class constantPoolHandle; +class SymbolClosure; + +class SymbolTable : public AllStatic { friend class VMStructs; friend class Symbol; friend class ClassFileParser; friend class SymbolTableConfig; friend class SymbolTableCreateEntry; -private: - static void delete_symbol(Symbol* sym); - void grow(JavaThread* jt); - void clean_dead_entries(JavaThread* jt); + private: + static volatile bool _has_work; - // The symbol table - static SymbolTable* _the_table; - static volatile bool _lookup_shared_first; - static volatile bool _alt_hash; + // Set if one bucket is out of balance due to hash algorithm deficiency + static volatile bool _needs_rehashing; - // For statistics - volatile size_t _symbols_removed; - volatile size_t _symbols_counted; + static void delete_symbol(Symbol* sym); + static void grow(JavaThread* jt); + static void clean_dead_entries(JavaThread* jt); - SymbolTableHash* _local_table; - size_t _current_size; - volatile bool _has_work; - // Set if one bucket is out of balance due to hash algorithm deficiency - volatile bool _needs_rehashing; + static double get_load_factor(); - volatile size_t _items_count; - volatile bool _has_items_to_clean; - - double get_load_factor() const; - - void check_concurrent_work(); + static void check_concurrent_work(); static void item_added(); static void item_removed(); // For cleaning - void reset_has_items_to_clean(); - void mark_has_items_to_clean(); - bool has_items_to_clean() const; + static void reset_has_items_to_clean(); + static void mark_has_items_to_clean(); + static bool has_items_to_clean(); - SymbolTable(); - - Symbol* allocate_symbol(const char* name, int len, bool c_heap); // Assumes no characters larger than 0x7F - Symbol* do_lookup(const char* name, int len, uintx hash); - Symbol* do_add_if_needed(const char* name, int len, uintx hash, bool heap); + static Symbol* allocate_symbol(const char* name, int len, bool c_heap); // Assumes no characters larger than 0x7F + static Symbol* do_lookup(const char* name, int len, uintx hash); + static Symbol* do_add_if_needed(const char* name, int len, uintx hash, bool heap); // lookup only, won't add. Also calculate hash. Used by the ClassfileParser. static Symbol* lookup_only(const char* name, int len, unsigned int& hash); @@ -154,27 +138,22 @@ int* cp_indices, unsigned int* hashValues); static Symbol* lookup_shared(const char* name, int len, unsigned int hash); - Symbol* lookup_dynamic(const char* name, int len, unsigned int hash); - Symbol* lookup_common(const char* name, int len, unsigned int hash); + static Symbol* lookup_dynamic(const char* name, int len, unsigned int hash); + static Symbol* lookup_common(const char* name, int len, unsigned int hash); // Arena for permanent symbols (null class loader) that are never unloaded static Arena* _arena; static Arena* arena() { return _arena; } // called for statistics - static void initialize_symbols(int arena_alloc_size = 0); + static void print_table_statistics(outputStream* st, const char* table_name); - void concurrent_work(JavaThread* jt); - void print_table_statistics(outputStream* st, const char* table_name); - - void try_rehash_table(); - bool do_rehash(); - inline void update_needs_rehash(bool rehash); + static void try_rehash_table(); + static bool do_rehash(); public: // The symbol table - static SymbolTable* the_table() { return _the_table; } - size_t table_size(); - TableStatistics get_table_statistics(); + static size_t table_size(); + static TableStatistics get_table_statistics(); enum { symbol_alloc_batch_size = 8, @@ -182,14 +161,10 @@ symbol_alloc_arena_size = 360*K // TODO (revisit) }; - static void create_table() { - assert(_the_table == NULL, "One symbol table allowed."); - _the_table = new SymbolTable(); - initialize_symbols(symbol_alloc_arena_size); - } + static void create_table(); static void do_concurrent_work(JavaThread* jt); - static bool has_work() { return the_table()->_has_work; } + static bool has_work() { return _has_work; } static void trigger_cleanup(); // Probing @@ -220,8 +195,12 @@ // Rehash the string table if it gets out of balance static void rehash_table(); - static bool needs_rehashing() - { return SymbolTable::the_table()->_needs_rehashing; } + static bool needs_rehashing() { return _needs_rehashing; } + static inline void update_needs_rehash(bool rehash) { + if (rehash) { + _needs_rehashing = true; + } + } // Heap dumper and CDS static void symbols_do(SymbolClosure *cl); diff -r 4f1f939d8f5d -r ea619918de95 src/hotspot/share/jfr/periodic/jfrPeriodic.cpp --- a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp Thu May 16 16:40:48 2019 +0530 +++ b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp Thu May 16 07:09:17 2019 -0400 @@ -525,12 +525,12 @@ } TRACE_REQUEST_FUNC(SymbolTableStatistics) { - TableStatistics statistics = SymbolTable::the_table()->get_table_statistics(); + TableStatistics statistics = SymbolTable::get_table_statistics(); emit_table_statistics(statistics); } TRACE_REQUEST_FUNC(StringTableStatistics) { - TableStatistics statistics = StringTable::the_table()->get_table_statistics(); + TableStatistics statistics = StringTable::get_table_statistics(); emit_table_statistics(statistics); } diff -r 4f1f939d8f5d -r ea619918de95 src/hotspot/share/prims/resolvedMethodTable.cpp --- a/src/hotspot/share/prims/resolvedMethodTable.cpp Thu May 16 16:40:48 2019 +0530 +++ b/src/hotspot/share/prims/resolvedMethodTable.cpp Thu May 16 07:09:17 2019 -0400 @@ -56,6 +56,10 @@ return name_hash ^ signature_hash; } +typedef ConcurrentHashTable, + ResolvedMethodTableConfig, + mtClass> ResolvedMethodTableHash; + class ResolvedMethodTableConfig : public ResolvedMethodTableHash::BaseConfig { private: public: @@ -83,14 +87,14 @@ } }; -ResolvedMethodTableHash* ResolvedMethodTable::_local_table = NULL; -size_t ResolvedMethodTable::_current_size = (size_t)1 << ResolvedMethodTableSizeLog; +static ResolvedMethodTableHash* _local_table = NULL; +static size_t _current_size = (size_t)1 << ResolvedMethodTableSizeLog; OopStorage* ResolvedMethodTable::_weak_handles = NULL; +volatile bool ResolvedMethodTable::_has_work = false; -volatile bool ResolvedMethodTable::_has_work = false; -volatile size_t ResolvedMethodTable::_items_count = 0; -volatile size_t ResolvedMethodTable::_uncleaned_items_count = 0; +volatile size_t _items_count = 0; +volatile size_t _uncleaned_items_count = 0; void ResolvedMethodTable::create_table() { _local_table = new ResolvedMethodTableHash(ResolvedMethodTableSizeLog, END_SIZE, GROW_HINT); @@ -209,14 +213,6 @@ log_trace(membername, table) ("ResolvedMethod entry removed"); } -bool ResolvedMethodTable::has_work() { - return _has_work; -} - -OopStorage* ResolvedMethodTable::weak_storage() { - return _weak_handles; -} - double ResolvedMethodTable::get_load_factor() { return (double)_items_count/_current_size; } diff -r 4f1f939d8f5d -r ea619918de95 src/hotspot/share/prims/resolvedMethodTable.hpp --- a/src/hotspot/share/prims/resolvedMethodTable.hpp Thu May 16 16:40:48 2019 +0530 +++ b/src/hotspot/share/prims/resolvedMethodTable.hpp Thu May 16 07:09:17 2019 -0400 @@ -26,28 +26,17 @@ #define SHARE_PRIMS_RESOLVEDMETHODTABLE_HPP #include "gc/shared/oopStorage.hpp" -#include "gc/shared/oopStorageParState.hpp" #include "memory/allocation.hpp" #include "oops/symbol.hpp" #include "oops/weakHandle.hpp" -#include "utilities/concurrentHashTable.hpp" -#include "utilities/hashtable.hpp" class ResolvedMethodTable; class ResolvedMethodTableConfig; -typedef ConcurrentHashTable, ResolvedMethodTableConfig, mtClass> ResolvedMethodTableHash; class ResolvedMethodTable : public AllStatic { - static ResolvedMethodTableHash* _local_table; - static size_t _current_size; - static OopStorage* _weak_handles; static volatile bool _has_work; - - static volatile size_t _items_count; - static volatile size_t _uncleaned_items_count; - public: // Initialization static void create_table(); @@ -63,10 +52,10 @@ static void item_removed(); // Cleaning - static bool has_work(); + static bool has_work() { return _has_work; } // GC Support - Backing storage for the oop*s - static OopStorage* weak_storage(); + static OopStorage* weak_storage() { return _weak_handles; } // Cleaning and table management