8223956: Make SymbolTable and StringTable AllStatic
Summary: Removed superfluous and confusing _the_table pointer.
Reviewed-by: gziemski, rehn
--- 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<WeakHandle<vm_string_table_data>,
+ 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<false /* concurrent */, false /* const */>*
- _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<oop>* oops =
new (ResourceObj::C_HEAP, mtInternal)
- GrowableArray<oop>((int)the_table()->_current_size, true);
+ GrowableArray<oop>((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);
--- 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<WeakHandle<vm_string_table_data>,
- StringTableConfig, mtSymbol> StringTableHash;
-
class StringTableCreateEntry;
class StringTable : public CHeapObj<mtSymbol>{
@@ -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<false /* concurrent */, false /* const*/>* 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);
--- 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<Symbol*,
+ SymbolTableConfig, mtSymbol> 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);
--- 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<Symbol*,
- SymbolTableConfig, mtSymbol> SymbolTableHash;
-
class SymbolTableCreateEntry;
-class SymbolTable : public CHeapObj<mtSymbol> {
+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);
--- 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<EventSymbolTableStatistics>(statistics);
}
TRACE_REQUEST_FUNC(StringTableStatistics) {
- TableStatistics statistics = StringTable::the_table()->get_table_statistics();
+ TableStatistics statistics = StringTable::get_table_statistics();
emit_table_statistics<EventStringTableStatistics>(statistics);
}
--- 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<WeakHandle<vm_resolved_method_table_data>,
+ 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;
}
--- 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<WeakHandle<vm_resolved_method_table_data>, 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