8306738: Select num workers for safepoint ParallelCleanupTask

Reviewed-by: shade, coleenp, tschatzl
This commit is contained in:
Axel Boldt-Christmas 2023-05-09 14:04:26 +00:00
parent a05560d993
commit 672bade522
7 changed files with 116 additions and 12 deletions

View file

@ -116,6 +116,8 @@ static size_t _current_size = 0;
static volatile size_t _items_count = 0; static volatile size_t _items_count = 0;
volatile bool _alt_hash = false; volatile bool _alt_hash = false;
static bool _rehashed = false;
static uint64_t _alt_hash_seed = 0; static uint64_t _alt_hash_seed = 0;
uintx hash_string(const jchar* s, int len, bool useAlt) { uintx hash_string(const jchar* s, int len, bool useAlt) {
@ -529,20 +531,46 @@ bool StringTable::do_rehash() {
return true; return true;
} }
bool StringTable::should_grow() {
return get_load_factor() > PREF_AVG_LIST_LEN && !_local_table->is_max_size_reached();
}
bool StringTable::rehash_table_expects_safepoint_rehashing() {
// No rehashing required
if (!needs_rehashing()) {
return false;
}
// Grow instead of rehash
if (should_grow()) {
return false;
}
// Already rehashed
if (_rehashed) {
return false;
}
// Resizing in progress
if (!_local_table->is_safepoint_safe()) {
return false;
}
return true;
}
void StringTable::rehash_table() { void StringTable::rehash_table() {
static bool rehashed = false;
log_debug(stringtable)("Table imbalanced, rehashing called."); log_debug(stringtable)("Table imbalanced, rehashing called.");
// Grow instead of rehash. // Grow instead of rehash.
if (get_load_factor() > PREF_AVG_LIST_LEN && if (should_grow()) {
!_local_table->is_max_size_reached()) {
log_debug(stringtable)("Choosing growing over rehashing."); log_debug(stringtable)("Choosing growing over rehashing.");
trigger_concurrent_work(); trigger_concurrent_work();
_needs_rehashing = false; _needs_rehashing = false;
return; return;
} }
// Already rehashed. // Already rehashed.
if (rehashed) { if (_rehashed) {
log_warning(stringtable)("Rehashing already done, still long lists."); log_warning(stringtable)("Rehashing already done, still long lists.");
trigger_concurrent_work(); trigger_concurrent_work();
_needs_rehashing = false; _needs_rehashing = false;
@ -552,7 +580,7 @@ void StringTable::rehash_table() {
_alt_hash_seed = AltHashing::compute_seed(); _alt_hash_seed = AltHashing::compute_seed();
{ {
if (do_rehash()) { if (do_rehash()) {
rehashed = true; _rehashed = true;
} else { } else {
log_info(stringtable)("Resizes in progress rehashing skipped."); log_info(stringtable)("Resizes in progress rehashing skipped.");
} }

View file

@ -96,6 +96,11 @@ class StringTable : public CHeapObj<mtSymbol>{
static oop intern(const char *utf8_string, TRAPS); static oop intern(const char *utf8_string, TRAPS);
// Rehash the string table if it gets out of balance // Rehash the string table if it gets out of balance
private:
static bool should_grow();
public:
static bool rehash_table_expects_safepoint_rehashing();
static void rehash_table(); static void rehash_table();
static bool needs_rehashing() { return _needs_rehashing; } static bool needs_rehashing() { return _needs_rehashing; }
static inline void update_needs_rehash(bool rehash) { static inline void update_needs_rehash(bool rehash) {

View file

@ -103,6 +103,7 @@ static THREAD_LOCAL bool _lookup_shared_first = false;
// Static arena for symbols that are not deallocated // Static arena for symbols that are not deallocated
Arena* SymbolTable::_arena = nullptr; Arena* SymbolTable::_arena = nullptr;
static bool _rehashed = false;
static uint64_t _alt_hash_seed = 0; static uint64_t _alt_hash_seed = 0;
static inline void log_trace_symboltable_helper(Symbol* sym, const char* msg) { static inline void log_trace_symboltable_helper(Symbol* sym, const char* msg) {
@ -805,13 +806,39 @@ bool SymbolTable::do_rehash() {
return true; return true;
} }
bool SymbolTable::should_grow() {
return get_load_factor() > PREF_AVG_LIST_LEN && !_local_table->is_max_size_reached();
}
bool SymbolTable::rehash_table_expects_safepoint_rehashing() {
// No rehashing required
if (!needs_rehashing()) {
return false;
}
// Grow instead of rehash
if (should_grow()) {
return false;
}
// Already rehashed
if (_rehashed) {
return false;
}
// Resizing in progress
if (!_local_table->is_safepoint_safe()) {
return false;
}
return true;
}
void SymbolTable::rehash_table() { void SymbolTable::rehash_table() {
static bool rehashed = false;
log_debug(symboltable)("Table imbalanced, rehashing called."); log_debug(symboltable)("Table imbalanced, rehashing called.");
// Grow instead of rehash. // Grow instead of rehash.
if (get_load_factor() > PREF_AVG_LIST_LEN && if (should_grow()) {
!_local_table->is_max_size_reached()) {
log_debug(symboltable)("Choosing growing over rehashing."); log_debug(symboltable)("Choosing growing over rehashing.");
trigger_cleanup(); trigger_cleanup();
_needs_rehashing = false; _needs_rehashing = false;
@ -819,7 +846,7 @@ void SymbolTable::rehash_table() {
} }
// Already rehashed. // Already rehashed.
if (rehashed) { if (_rehashed) {
log_warning(symboltable)("Rehashing already done, still long lists."); log_warning(symboltable)("Rehashing already done, still long lists.");
trigger_cleanup(); trigger_cleanup();
_needs_rehashing = false; _needs_rehashing = false;
@ -829,7 +856,7 @@ void SymbolTable::rehash_table() {
_alt_hash_seed = AltHashing::compute_seed(); _alt_hash_seed = AltHashing::compute_seed();
if (do_rehash()) { if (do_rehash()) {
rehashed = true; _rehashed = true;
} else { } else {
log_info(symboltable)("Resizes in progress rehashing skipped."); log_info(symboltable)("Resizes in progress rehashing skipped.");
} }

View file

@ -144,6 +144,11 @@ public:
static Symbol* new_permanent_symbol(const char* name); static Symbol* new_permanent_symbol(const char* name);
// Rehash the string table if it gets out of balance // Rehash the string table if it gets out of balance
private:
static bool should_grow();
public:
static bool rehash_table_expects_safepoint_rehashing();
static void rehash_table(); static void rehash_table();
static bool needs_rehashing() { return _needs_rehashing; } static bool needs_rehashing() { return _needs_rehashing; }
static inline void update_needs_rehash(bool rehash) { static inline void update_needs_rehash(bool rehash) {

View file

@ -161,6 +161,20 @@ void InlineCacheBuffer::refill_ic_stubs() {
VMThread::execute(&ibf); VMThread::execute(&ibf);
} }
bool InlineCacheBuffer::needs_update_inline_caches() {
// Stub removal
if (buffer()->number_of_stubs() > 0) {
return true;
}
// Release pending CompiledICHolder
if (pending_icholder_count() > 0) {
return true;
}
return false;
}
void InlineCacheBuffer::update_inline_caches() { void InlineCacheBuffer::update_inline_caches() {
if (buffer()->number_of_stubs() > 0) { if (buffer()->number_of_stubs() > 0) {
if (TraceICBuffer) { if (TraceICBuffer) {

View file

@ -167,6 +167,7 @@ class InlineCacheBuffer: public AllStatic {
static bool contains(address instruction_address); static bool contains(address instruction_address);
// removes the ICStubs after backpatching // removes the ICStubs after backpatching
static bool needs_update_inline_caches();
static void update_inline_caches(); static void update_inline_caches();
static void refill_ic_stubs(); static void refill_ic_stubs();

View file

@ -547,6 +547,28 @@ public:
_do_lazy_roots(!VMThread::vm_operation()->skip_thread_oop_barriers() && _do_lazy_roots(!VMThread::vm_operation()->skip_thread_oop_barriers() &&
Universe::heap()->uses_stack_watermark_barrier()) {} Universe::heap()->uses_stack_watermark_barrier()) {}
uint expected_num_workers() const {
uint workers = 0;
if (SymbolTable::rehash_table_expects_safepoint_rehashing()) {
workers++;
}
if (StringTable::rehash_table_expects_safepoint_rehashing()) {
workers++;
}
if (InlineCacheBuffer::needs_update_inline_caches()) {
workers++;
}
if (_do_lazy_roots) {
workers++;
}
return MAX2<uint>(1, workers);
}
void work(uint worker_id) { void work(uint worker_id) {
// These tasks are ordered by relative length of time to execute so that potentially longer tasks start first. // These tasks are ordered by relative length of time to execute so that potentially longer tasks start first.
if (_subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_SYMBOL_TABLE_REHASH)) { if (_subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_SYMBOL_TABLE_REHASH)) {
@ -601,9 +623,11 @@ void SafepointSynchronize::do_cleanup_tasks() {
assert(heap != nullptr, "heap not initialized yet?"); assert(heap != nullptr, "heap not initialized yet?");
ParallelCleanupTask cleanup; ParallelCleanupTask cleanup;
WorkerThreads* cleanup_workers = heap->safepoint_workers(); WorkerThreads* cleanup_workers = heap->safepoint_workers();
if (cleanup_workers != nullptr) { const uint expected_num_workers = cleanup.expected_num_workers();
if (cleanup_workers != nullptr && expected_num_workers > 1) {
// Parallel cleanup using GC provided thread pool. // Parallel cleanup using GC provided thread pool.
cleanup_workers->run_task(&cleanup); const uint num_workers = MIN2(expected_num_workers, cleanup_workers->active_workers());
cleanup_workers->run_task(&cleanup, num_workers);
} else { } else {
// Serial cleanup using VMThread. // Serial cleanup using VMThread.
cleanup.work(0); cleanup.work(0);