Skip to content
Permalink
Browse files

8230940: Obsolete MonitorBound

Obsolete MonitorBound option and delete associated code.

Reviewed-by: kbarrett, dholmes, redestad
  • Loading branch information
Daniel D. Daugherty
Daniel D. Daugherty committed May 3, 2020
1 parent 765a5b8 commit 57fbf93ef90e01a057b7d58c9c660c64829a384f
@@ -522,7 +522,6 @@ static SpecialFlag const special_jvm_flags[] = {
{ "UseMembar", JDK_Version::jdk(10), JDK_Version::jdk(12), JDK_Version::undefined() },
{ "AllowRedefinitionToAddDeleteMethods", JDK_Version::jdk(13), JDK_Version::undefined(), JDK_Version::undefined() },
{ "FlightRecorder", JDK_Version::jdk(13), JDK_Version::undefined(), JDK_Version::undefined() },
{ "MonitorBound", JDK_Version::jdk(14), JDK_Version::jdk(15), JDK_Version::jdk(16) },
{ "PrintVMQWaitTime", JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
{ "UseNewFieldLayout", JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
{ "ForceNUMA", JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
@@ -550,6 +549,7 @@ static SpecialFlag const special_jvm_flags[] = {
{ "UseSSE", JDK_Version::undefined(), JDK_Version::jdk(15), JDK_Version::jdk(16) },
#endif // !X86
{ "UseAdaptiveGCBoundary", JDK_Version::undefined(), JDK_Version::jdk(15), JDK_Version::jdk(16) },
{ "MonitorBound", JDK_Version::jdk(14), JDK_Version::jdk(15), JDK_Version::jdk(16) },

#ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS
// These entries will generate build errors. Their purpose is to test the macros.
@@ -426,7 +426,7 @@ void JVMFlag::print_on(outputStream* st, bool withComments, bool printRanges) {
// double MinRAMPercentage [ 0.000 ... 100.000 ] {product} {default}
// uintx MinSurvivorRatio [ 3 ... 18446744073709551615 ] {product} {default}
// size_t MinTLABSize [ 1 ... 9223372036854775807 ] {product} {default}
// intx MonitorBound [ 0 ... 2147483647 ] {product} {default}
// intx MaxInlineSize [ 0 ... 2147483647 ] {product} {default}
// | | | | | |
// | | | | | +-- col7
// | | | | +-- col6
@@ -691,9 +691,6 @@ const size_t minimumSymbolTableSize = 1024;
"Use LWP-based instead of libthread-based synchronization " \
"(SPARC only)") \
\
product(intx, MonitorBound, 0, "(Deprecated) Bound Monitor population") \
range(0, max_jint) \
\
experimental(intx, MonitorUsedDeflationThreshold, 90, \
"Percentage of used monitors before triggering cleanup " \
"safepoint which deflates monitors (0 is off). " \
@@ -499,10 +499,6 @@ bool SafepointSynchronize::is_cleanup_needed() {
return false;
}

bool SafepointSynchronize::is_forced_cleanup_needed() {
return ObjectSynchronizer::needs_monitor_scavenge();
}

class ParallelSPCleanupThreadClosure : public ThreadClosure {
private:
CodeBlobClosure* _nmethod_cl;
@@ -162,7 +162,6 @@ class SafepointSynchronize : AllStatic {
static void handle_polling_page_exception(JavaThread *thread);

static bool is_cleanup_needed();
static bool is_forced_cleanup_needed();
static void do_cleanup_tasks();

static void set_is_at_safepoint() { _state = _synchronized; }
@@ -781,7 +781,6 @@ struct SharedGlobals {
};

static SharedGlobals GVars;
static int _forceMonitorScavenge = 0; // Scavenge required and pending

static markWord read_stable_mark(oop obj) {
markWord mark = obj->mark();
@@ -1170,27 +1169,8 @@ static bool monitors_used_above_threshold() {
return false;
}

// Returns true if MonitorBound is set (> 0) and if the specified
// cnt is > MonitorBound. Otherwise returns false.
static bool is_MonitorBound_exceeded(const int cnt) {
const int mx = MonitorBound;
return mx > 0 && cnt > mx;
}

bool ObjectSynchronizer::is_cleanup_needed() {
if (monitors_used_above_threshold()) {
// Too many monitors in use.
return true;
}
return needs_monitor_scavenge();
}

bool ObjectSynchronizer::needs_monitor_scavenge() {
if (Atomic::load(&_forceMonitorScavenge) == 1) {
log_info(monitorinflation)("Monitor scavenge needed, triggering safepoint cleanup.");
return true;
}
return false;
return monitors_used_above_threshold();
}

void ObjectSynchronizer::oops_do(OopClosure* f) {
@@ -1237,41 +1217,6 @@ void ObjectSynchronizer::list_oops_do(ObjectMonitor* list, OopClosure* f) {
// -- assigned to an object. The object is inflated and the mark refers
// to the ObjectMonitor.


// Constraining monitor pool growth via MonitorBound ...
//
// If MonitorBound is not set (<= 0), MonitorBound checks are disabled.
//
// The monitor pool is grow-only. We scavenge at STW safepoint-time, but the
// the rate of scavenging is driven primarily by GC. As such, we can find
// an inordinate number of monitors in circulation.
// To avoid that scenario we can artificially induce a STW safepoint
// if the pool appears to be growing past some reasonable bound.
// Generally we favor time in space-time tradeoffs, but as there's no
// natural back-pressure on the # of extant monitors we need to impose some
// type of limit. Beware that if MonitorBound is set to too low a value
// we could just loop. In addition, if MonitorBound is set to a low value
// we'll incur more safepoints, which are harmful to performance.
// See also: GuaranteedSafepointInterval
//
// If MonitorBound is set, the boundry applies to
// (om_list_globals._population - om_list_globals._free_count)
// i.e., if there are not enough ObjectMonitors on the global free list,
// then a safepoint deflation is induced. Picking a good MonitorBound value
// is non-trivial.

static void InduceScavenge(Thread* self, const char * Whence) {
// Induce STW safepoint to trim monitors
// Ultimately, this results in a call to deflate_idle_monitors() in the near future.
// More precisely, trigger a cleanup safepoint as the number
// of active monitors passes the specified threshold.
// TODO: assert thread state is reasonable

if (Atomic::xchg(&_forceMonitorScavenge, 1) == 0) {
VMThread::check_for_forced_cleanup();
}
}

ObjectMonitor* ObjectSynchronizer::om_alloc(Thread* self) {
// A large MAXPRIVATE value reduces both list lock contention
// and list coherency traffic, but also tends to increase the
@@ -1315,15 +1260,6 @@ ObjectMonitor* ObjectSynchronizer::om_alloc(Thread* self) {
}
self->om_free_provision += 1 + (self->om_free_provision / 2);
if (self->om_free_provision > MAXPRIVATE) self->om_free_provision = MAXPRIVATE;

if (is_MonitorBound_exceeded(Atomic::load(&om_list_globals._population) -
Atomic::load(&om_list_globals._free_count))) {
// Not enough ObjectMonitors on the global free list.
// We can't safely induce a STW safepoint from om_alloc() as our thread
// state may not be appropriate for such activities and callers may hold
// naked oops, so instead we defer the action.
InduceScavenge(self, "om_alloc");
}
continue;
}

@@ -2025,8 +1961,6 @@ void ObjectSynchronizer::finish_deflate_idle_monitors(DeflateMonitorCounters* co
Atomic::load(&om_list_globals._free_count));
}

Atomic::store(&_forceMonitorScavenge, 0); // Reset

OM_PERFDATA_OP(Deflations, inc(counters->n_scavenged));
OM_PERFDATA_OP(MonExtant, set_value(counters->n_in_circulation));

@@ -145,7 +145,6 @@ class ObjectSynchronizer : AllStatic {
ObjectMonitor** free_head_p,
ObjectMonitor** free_tail_p);
static bool is_cleanup_needed();
static bool needs_monitor_scavenge();
static void oops_do(OopClosure* f);
// Process oops in thread local used monitors
static void thread_local_used_oops_do(Thread* thread, OopClosure* f);
@@ -400,11 +400,6 @@ class HandshakeALotClosure : public HandshakeClosure {
}
};

void VMThread::check_for_forced_cleanup() {
MonitorLocker mq(VMOperationQueue_lock, Mutex::_no_safepoint_check_flag);
mq.notify();
}

VM_Operation* VMThread::no_op_safepoint() {
// Check for handshakes first since we may need to return a VMop.
if (HandshakeALot) {
@@ -415,8 +410,7 @@ VM_Operation* VMThread::no_op_safepoint() {
long interval_ms = SafepointTracing::time_since_last_safepoint_ms();
bool max_time_exceeded = GuaranteedSafepointInterval != 0 &&
(interval_ms >= GuaranteedSafepointInterval);
if ((max_time_exceeded && SafepointSynchronize::is_cleanup_needed()) ||
SafepointSynchronize::is_forced_cleanup_needed()) {
if (max_time_exceeded && SafepointSynchronize::is_cleanup_needed()) {
return &cleanup_op;
}
if (SafepointALot) {
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2020, 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
@@ -136,7 +136,6 @@ class VMThread: public NamedThread {

// The ever running loop for the VMThread
void loop();
static void check_for_forced_cleanup();

// Called to stop the VM thread
static void wait_for_vm_thread_exit();

0 comments on commit 57fbf93

Please sign in to comment.