8153224: Monitor deflation prolong safepoints

Add support for AsyncDeflateIdleMonitors (default true); the async deflation work is performed by the ServiceThread.

Co-authored-by: Carsten Varming <varming@gmail.com>
Reviewed-by: dcubed, rehn, rkennke, cvarming, coleenp, acorn, dholmes, eosterlund
This commit is contained in:
Daniel D. Daugherty 2020-06-01 23:37:14 -04:00
parent 30aa1b0689
commit 00f223e22f
23 changed files with 1496 additions and 250 deletions

View file

@ -43,11 +43,11 @@ class ThreadsList;
typedef PaddedEnd<ObjectMonitor, OM_CACHE_LINE_SIZE> PaddedObjectMonitor;
struct DeflateMonitorCounters {
int n_in_use; // currently associated with objects
int n_in_circulation; // extant
int n_scavenged; // reclaimed (global and per-thread)
int per_thread_scavenged; // per-thread scavenge total
double per_thread_times; // per-thread scavenge times
volatile int n_in_use; // currently associated with objects
volatile int n_in_circulation; // extant
volatile int n_scavenged; // reclaimed (global and per-thread)
volatile int per_thread_scavenged; // per-thread scavenge total
double per_thread_times; // per-thread scavenge times
};
class ObjectSynchronizer : AllStatic {
@ -132,6 +132,10 @@ class ObjectSynchronizer : AllStatic {
// Basically we deflate all monitors that are not busy.
// An adaptive profile-based deflation policy could be used if needed
static void deflate_idle_monitors(DeflateMonitorCounters* counters);
static void deflate_idle_monitors_using_JT();
static void deflate_global_idle_monitors_using_JT();
static void deflate_per_thread_idle_monitors_using_JT(JavaThread* target);
static void deflate_common_idle_monitors_using_JT(bool is_global, JavaThread* target);
static void deflate_thread_local_monitors(Thread* thread, DeflateMonitorCounters* counters);
static void prepare_deflate_idle_monitors(DeflateMonitorCounters* counters);
static void finish_deflate_idle_monitors(DeflateMonitorCounters* counters);
@ -141,10 +145,26 @@ class ObjectSynchronizer : AllStatic {
int* count_p,
ObjectMonitor** free_head_p,
ObjectMonitor** free_tail_p);
// For a given in-use monitor list: global or per-thread, deflate idle
// monitors using a JavaThread.
static int deflate_monitor_list_using_JT(ObjectMonitor** list_p,
int* count_p,
ObjectMonitor** free_head_p,
ObjectMonitor** free_tail_p,
ObjectMonitor** saved_mid_in_use_p);
static bool deflate_monitor(ObjectMonitor* mid, oop obj,
ObjectMonitor** free_head_p,
ObjectMonitor** free_tail_p);
static bool is_cleanup_needed();
static bool deflate_monitor_using_JT(ObjectMonitor* mid,
ObjectMonitor** free_head_p,
ObjectMonitor** free_tail_p);
static bool is_async_deflation_needed();
static bool is_safepoint_deflation_needed();
static bool is_async_deflation_requested() { return _is_async_deflation_requested; }
static bool is_special_deflation_requested() { return _is_special_deflation_requested; }
static void set_is_async_deflation_requested(bool new_value) { _is_async_deflation_requested = new_value; }
static void set_is_special_deflation_requested(bool new_value) { _is_special_deflation_requested = new_value; }
static jlong time_since_last_async_deflation_ms();
static void oops_do(OopClosure* f);
// Process oops in thread local used monitors
static void thread_local_used_oops_do(Thread* thread, OopClosure* f);
@ -155,6 +175,8 @@ class ObjectSynchronizer : AllStatic {
outputStream * out, int *error_cnt_p);
static void chk_global_free_list_and_count(outputStream * out,
int *error_cnt_p);
static void chk_global_wait_list_and_count(outputStream * out,
int *error_cnt_p);
static void chk_global_in_use_list_and_count(outputStream * out,
int *error_cnt_p);
static void chk_in_use_entry(JavaThread* jt, ObjectMonitor* n,
@ -169,12 +191,17 @@ class ObjectSynchronizer : AllStatic {
static int log_monitor_list_counts(outputStream * out);
static int verify_objmon_isinpool(ObjectMonitor *addr) PRODUCT_RETURN0;
static void do_safepoint_work(DeflateMonitorCounters* counters);
private:
friend class SynchronizerTest;
enum { _BLOCKSIZE = 128 };
// global list of blocks of monitors
static PaddedObjectMonitor* g_block_list;
static volatile bool _is_async_deflation_requested;
static volatile bool _is_special_deflation_requested;
static jlong _last_async_deflation_time_ns;
// Function to prepend new blocks to the appropriate lists:
static void prepend_block_to_lists(PaddedObjectMonitor* new_blk);