mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8061553: Contended Locking fast enter bucket
JEP-143/JDK-8061553 Contended Locking fast enter bucket Co-authored-by: Dave Dice <dave.dice@oracle.com> Co-authored-by: Karen Kinnear <karen.kinnear@oracle.com> Reviewed-by: dholmes, acorn
This commit is contained in:
parent
3d3f6553c0
commit
a9e28164eb
6 changed files with 96 additions and 54 deletions
|
@ -122,6 +122,70 @@ static volatile int MonitorFreeCount = 0; // # on gFreeList
|
|||
static volatile int MonitorPopulation = 0; // # Extant -- in circulation
|
||||
#define CHAINMARKER (cast_to_oop<intptr_t>(-1))
|
||||
|
||||
|
||||
// =====================> Quick functions
|
||||
|
||||
// The quick_* forms are special fast-path variants used to improve
|
||||
// performance. In the simplest case, a "quick_*" implementation could
|
||||
// simply return false, in which case the caller will perform the necessary
|
||||
// state transitions and call the slow-path form.
|
||||
// The fast-path is designed to handle frequently arising cases in an efficient
|
||||
// manner and is just a degenerate "optimistic" variant of the slow-path.
|
||||
// returns true -- to indicate the call was satisfied.
|
||||
// returns false -- to indicate the call needs the services of the slow-path.
|
||||
// A no-loitering ordinance is in effect for code in the quick_* family
|
||||
// operators: safepoints or indefinite blocking (blocking that might span a
|
||||
// safepoint) are forbidden. Generally the thread_state() is _in_Java upon
|
||||
// entry.
|
||||
|
||||
// The LockNode emitted directly at the synchronization site would have
|
||||
// been too big if it were to have included support for the cases of inflated
|
||||
// recursive enter and exit, so they go here instead.
|
||||
// Note that we can't safely call AsyncPrintJavaStack() from within
|
||||
// quick_enter() as our thread state remains _in_Java.
|
||||
|
||||
bool ObjectSynchronizer::quick_enter(oop obj, Thread * Self,
|
||||
BasicLock * Lock) {
|
||||
assert(!SafepointSynchronize::is_at_safepoint(), "invariant");
|
||||
assert(Self->is_Java_thread(), "invariant");
|
||||
assert(((JavaThread *) Self)->thread_state() == _thread_in_Java, "invariant");
|
||||
No_Safepoint_Verifier nsv;
|
||||
if (obj == NULL) return false; // Need to throw NPE
|
||||
const markOop mark = obj->mark();
|
||||
|
||||
if (mark->has_monitor()) {
|
||||
ObjectMonitor * const m = mark->monitor();
|
||||
assert(m->object() == obj, "invariant");
|
||||
Thread * const owner = (Thread *) m->_owner;
|
||||
|
||||
// Lock contention and Transactional Lock Elision (TLE) diagnostics
|
||||
// and observability
|
||||
// Case: light contention possibly amenable to TLE
|
||||
// Case: TLE inimical operations such as nested/recursive synchronization
|
||||
|
||||
if (owner == Self) {
|
||||
m->_recursions++;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (owner == NULL &&
|
||||
Atomic::cmpxchg_ptr(Self, &(m->_owner), NULL) == NULL) {
|
||||
assert(m->_recursions == 0, "invariant");
|
||||
assert(m->_owner == Self, "invariant");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Note that we could inflate in quick_enter.
|
||||
// This is likely a useful optimization
|
||||
// Critically, in quick_enter() we must not:
|
||||
// -- perform bias revocation, or
|
||||
// -- block indefinitely, or
|
||||
// -- reach a safepoint
|
||||
|
||||
return false; // revert to slow-path
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Fast Monitor Enter/Exit
|
||||
// This the fast monitor enter. The interpreter and compiler use
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue