8223956: Make SymbolTable and StringTable AllStatic

Removed superfluous and confusing _the_table pointer.

Reviewed-by: gziemski, rehn
This commit is contained in:
Coleen Phillimore 2019-05-16 07:09:17 -04:00
parent 5fc3474639
commit 4915cf9b71
7 changed files with 186 additions and 270 deletions

View file

@ -70,9 +70,26 @@ static OffsetCompactHashtable<
> _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 @@ public:
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 @@ static size_t ceil_log2(size_t value) {
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::delete_symbol(Symbol* sym) {
}
}
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 @@ size_t SymbolTable::table_size() {
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 @@ Symbol* SymbolTable::allocate_symbol(const char* name, int len, bool c_heap) {
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 @@ void SymbolTable::symbols_do(SymbolClosure *cl) {
// 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 @@ public:
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_dynamic(const char* name,
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::lookup_common(const char* name,
}
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 @@ Symbol* SymbolTable::new_symbol(const Symbol* sym, int begin, int end) {
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::do_lookup(const char* name, int len, uintx hash) {
}
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 @@ void SymbolTable::new_symbols(ClassLoaderData* loader_data, const constantPoolHa
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 @@ Symbol* SymbolTable::do_add_if_needed(const char* name, int len, uintx hash, boo
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 @@ Symbol* SymbolTable::new_permanent_symbol(const char* name) {
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 @@ public:
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 @@ public:
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 @@ struct CopyToArchive : StackObj {
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 @@ void SymbolTable::write_to_archive() {
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 @@ void SymbolTable::clean_dead_entries(JavaThread* jt) {
}
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::check_concurrent_work() {
}
}
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 @@ void SymbolTable::concurrent_work(JavaThread* jt) {
_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 @@ bool SymbolTable::do_rehash() {
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 @@ void SymbolTable::try_rehash_table() {
_needs_rehashing = false;
}
void SymbolTable::rehash_table() {
SymbolTable::the_table()->try_rehash_table();
}
//---------------------------------------------------------------------------
// Non-product code
@ -830,18 +827,17 @@ public:
};
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);