Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8332506: SIGFPE In ObjectSynchronizer::is_async_deflation_needed() #22815

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 33 additions & 20 deletions src/hotspot/share/runtime/synchronizer.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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;
Expand Down