8248391: Unify handling of all OopStorage instances in weak root processing

OopStorage instance now owned by subsystems, and generalize dead entry notification

Co-authored-by: Erik Osterlund <erik.osterlund@oracle.com>
Co-authored-by: Stefan Karlsson <stefan.karlsson@oracle.com>
Reviewed-by: coleenp, tschatzl
This commit is contained in:
Kim Barrett 2020-07-16 17:41:14 -04:00
parent 55af701cc3
commit a8d6a05ce8
42 changed files with 822 additions and 574 deletions

View file

@ -85,8 +85,7 @@ 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::_oop_storage;
static size_t _current_size = 0;
static volatile size_t _items_count = 0;
@ -129,7 +128,7 @@ class StringTableConfig : public StackObj {
return AllocateHeap(size, mtSymbol);
}
static void free_node(void* memory, Value const& value) {
value.release(OopStorageSet::string_table_weak());
value.release(StringTable::_oop_storage);
FreeHeap(memory);
StringTable::item_removed();
}
@ -211,30 +210,24 @@ void StringTable::create_table() {
log_trace(stringtable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")",
_current_size, start_size_log_2);
_local_table = new StringTableHash(start_size_log_2, END_SIZE, REHASH_LEN);
_oop_storage = OopStorageSet::create_weak("StringTable Weak");
_oop_storage->register_num_dead_callback(&gc_notification);
}
size_t StringTable::item_added() {
return Atomic::add(&_items_count, (size_t)1);
}
size_t StringTable::add_items_to_clean(size_t ndead) {
size_t total = Atomic::add(&_uncleaned_items_count, (size_t)ndead);
log_trace(stringtable)(
"Uncleaned items:" SIZE_FORMAT " added: " SIZE_FORMAT " total:" SIZE_FORMAT,
_uncleaned_items_count, ndead, total);
return total;
}
void StringTable::item_removed() {
Atomic::add(&_items_count, (size_t)-1);
}
double StringTable::get_load_factor() {
return (double)_items_count/_current_size;
return double(_items_count)/double(_current_size);
}
double StringTable::get_dead_factor() {
return (double)_uncleaned_items_count/_current_size;
double StringTable::get_dead_factor(size_t num_dead) {
return double(num_dead)/double(_current_size);
}
size_t StringTable::table_size() {
@ -243,7 +236,7 @@ size_t StringTable::table_size() {
void StringTable::trigger_concurrent_work() {
MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
_has_work = true;
Atomic::store(&_has_work, true);
Service_lock->notify_all();
}
@ -368,7 +361,7 @@ oop StringTable::do_intern(Handle string_or_null_h, const jchar* name,
bool rehash_warning;
do {
// Callers have already looked up the String using the jchar* name, so just go to add.
WeakHandle wh(OopStorageSet::string_table_weak(), string_h);
WeakHandle wh(_oop_storage, string_h);
// The hash table takes ownership of the WeakHandle, even if it's not inserted.
if (_local_table->insert(THREAD, lookup, wh, &rehash_warning)) {
update_needs_rehash(rehash_warning);
@ -449,13 +442,15 @@ void StringTable::clean_dead_entries(JavaThread* jt) {
log_debug(stringtable)("Cleaned %ld of %ld", stdc._count, stdc._item);
}
void StringTable::check_concurrent_work() {
if (_has_work) {
void StringTable::gc_notification(size_t num_dead) {
log_trace(stringtable)("Uncleaned items:" SIZE_FORMAT, num_dead);
if (has_work()) {
return;
}
double load_factor = StringTable::get_load_factor();
double dead_factor = StringTable::get_dead_factor();
double dead_factor = StringTable::get_dead_factor(num_dead);
// We should clean/resize if we have more dead than alive,
// more items than preferred load factor or
// more dead items than water mark.
@ -468,8 +463,11 @@ void StringTable::check_concurrent_work() {
}
}
bool StringTable::has_work() {
return Atomic::load_acquire(&_has_work);
}
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);
// We prefer growing, since that also removes dead items
@ -478,6 +476,7 @@ void StringTable::do_concurrent_work(JavaThread* jt) {
} else {
clean_dead_entries(jt);
}
Atomic::release_store(&_has_work, false);
}
// Rehash