8332506: SIGFPE In ObjectSynchronizer::is_async_deflation_needed()

Reviewed-by: coleenp, dholmes
This commit is contained in:
Fredrik Bredberg 2025-01-08 09:50:35 +00:00
parent 98724219a8
commit cbabc04515

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -1264,36 +1264,49 @@ static bool monitors_used_above_threshold(MonitorList* list) {
if (MonitorUsedDeflationThreshold == 0) { // disabled case is easy
return false;
}
// Start with ceiling based on a per-thread estimate:
size_t ceiling = ObjectSynchronizer::in_use_list_ceiling();
size_t old_ceiling = ceiling;
if (ceiling < list->max()) {
// The max used by the system has exceeded the ceiling so use that:
ceiling = list->max();
}
size_t monitors_used = list->count();
if (monitors_used == 0) { // empty list is easy
return false;
}
if (NoAsyncDeflationProgressMax != 0 &&
_no_progress_cnt >= NoAsyncDeflationProgressMax) {
double remainder = (100.0 - MonitorUsedDeflationThreshold) / 100.0;
size_t new_ceiling = ceiling + (size_t)((double)ceiling * remainder) + 1;
ObjectSynchronizer::set_in_use_list_ceiling(new_ceiling);
log_info(monitorinflation)("Too many deflations without progress; "
"bumping in_use_list_ceiling from " SIZE_FORMAT
" to " SIZE_FORMAT, old_ceiling, new_ceiling);
_no_progress_cnt = 0;
ceiling = new_ceiling;
}
size_t old_ceiling = ObjectSynchronizer::in_use_list_ceiling();
// Make sure that we use a ceiling value that is not lower than
// previous, not lower than the recorded max used by the system, and
// not lower than the current number of monitors in use (which can
// race ahead of max). The result is guaranteed > 0.
size_t ceiling = MAX3(old_ceiling, list->max(), monitors_used);
// Check if our monitor usage is above the threshold:
size_t monitor_usage = (monitors_used * 100LL) / ceiling;
if (int(monitor_usage) > MonitorUsedDeflationThreshold) {
// Deflate monitors if over the threshold percentage, unless no
// progress on previous deflations.
bool is_above_threshold = true;
// Check if it's time to adjust the in_use_list_ceiling up, due
// to too many async deflation attempts without any progress.
if (NoAsyncDeflationProgressMax != 0 &&
_no_progress_cnt >= NoAsyncDeflationProgressMax) {
double remainder = (100.0 - MonitorUsedDeflationThreshold) / 100.0;
size_t delta = (size_t)(ceiling * remainder) + 1;
size_t new_ceiling = (ceiling > SIZE_MAX - delta)
? SIZE_MAX // Overflow, let's clamp new_ceiling.
: ceiling + delta;
ObjectSynchronizer::set_in_use_list_ceiling(new_ceiling);
log_info(monitorinflation)("Too many deflations without progress; "
"bumping in_use_list_ceiling from " SIZE_FORMAT
" to " SIZE_FORMAT, old_ceiling, new_ceiling);
_no_progress_cnt = 0;
ceiling = new_ceiling;
// Check if our monitor usage is still above the threshold:
monitor_usage = (monitors_used * 100LL) / ceiling;
is_above_threshold = int(monitor_usage) > MonitorUsedDeflationThreshold;
}
log_info(monitorinflation)("monitors_used=" SIZE_FORMAT ", ceiling=" SIZE_FORMAT
", monitor_usage=" SIZE_FORMAT ", threshold=%d",
monitors_used, ceiling, monitor_usage, MonitorUsedDeflationThreshold);
return true;
return is_above_threshold;
}
return false;