8353584: [BACKOUT] DaCapo xalan performance with -XX:+UseObjectMonitorTable
Reviewed-by: rkennke
This commit is contained in:
parent
814730eae7
commit
e2e1598ecc
@ -27,7 +27,7 @@
|
|||||||
#include "runtime/objectMonitor.hpp"
|
#include "runtime/objectMonitor.hpp"
|
||||||
#include "runtime/synchronizer.hpp"
|
#include "runtime/synchronizer.hpp"
|
||||||
|
|
||||||
void BasicLock::print_on(outputStream* st, oop owner) {
|
void BasicLock::print_on(outputStream* st, oop owner) const {
|
||||||
st->print("monitor");
|
st->print("monitor");
|
||||||
if (UseObjectMonitorTable) {
|
if (UseObjectMonitorTable) {
|
||||||
ObjectMonitor* mon = object_monitor_cache();
|
ObjectMonitor* mon = object_monitor_cache();
|
||||||
|
@ -50,8 +50,6 @@ class BasicLock {
|
|||||||
static int metadata_offset_in_bytes() { return (int)offset_of(BasicLock, _metadata); }
|
static int metadata_offset_in_bytes() { return (int)offset_of(BasicLock, _metadata); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BasicLock() : _metadata(0) {}
|
|
||||||
|
|
||||||
// LM_MONITOR
|
// LM_MONITOR
|
||||||
void set_bad_metadata_deopt() { set_metadata(badDispHeaderDeopt); }
|
void set_bad_metadata_deopt() { set_metadata(badDispHeaderDeopt); }
|
||||||
|
|
||||||
@ -61,12 +59,12 @@ class BasicLock {
|
|||||||
static int displaced_header_offset_in_bytes() { return metadata_offset_in_bytes(); }
|
static int displaced_header_offset_in_bytes() { return metadata_offset_in_bytes(); }
|
||||||
|
|
||||||
// LM_LIGHTWEIGHT
|
// LM_LIGHTWEIGHT
|
||||||
inline ObjectMonitor* object_monitor_cache();
|
inline ObjectMonitor* object_monitor_cache() const;
|
||||||
inline void clear_object_monitor_cache();
|
inline void clear_object_monitor_cache();
|
||||||
inline void set_object_monitor_cache(ObjectMonitor* mon);
|
inline void set_object_monitor_cache(ObjectMonitor* mon);
|
||||||
static int object_monitor_cache_offset_in_bytes() { return metadata_offset_in_bytes(); }
|
static int object_monitor_cache_offset_in_bytes() { return metadata_offset_in_bytes(); }
|
||||||
|
|
||||||
void print_on(outputStream* st, oop owner);
|
void print_on(outputStream* st, oop owner) const;
|
||||||
|
|
||||||
// move a basic lock (used during deoptimization)
|
// move a basic lock (used during deoptimization)
|
||||||
void move_to(oop obj, BasicLock* dest);
|
void move_to(oop obj, BasicLock* dest);
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#define SHARE_RUNTIME_BASICLOCK_INLINE_HPP
|
#define SHARE_RUNTIME_BASICLOCK_INLINE_HPP
|
||||||
|
|
||||||
#include "runtime/basicLock.hpp"
|
#include "runtime/basicLock.hpp"
|
||||||
#include "runtime/objectMonitor.inline.hpp"
|
|
||||||
|
|
||||||
inline markWord BasicLock::displaced_header() const {
|
inline markWord BasicLock::displaced_header() const {
|
||||||
assert(LockingMode == LM_LEGACY, "must be");
|
assert(LockingMode == LM_LEGACY, "must be");
|
||||||
@ -38,15 +37,10 @@ inline void BasicLock::set_displaced_header(markWord header) {
|
|||||||
Atomic::store(&_metadata, header.value());
|
Atomic::store(&_metadata, header.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ObjectMonitor* BasicLock::object_monitor_cache() {
|
inline ObjectMonitor* BasicLock::object_monitor_cache() const {
|
||||||
assert(UseObjectMonitorTable, "must be");
|
assert(UseObjectMonitorTable, "must be");
|
||||||
#if !defined(ZERO) && (defined(X86) || defined(AARCH64) || defined(RISCV64) || defined(PPC64) || defined(S390))
|
#if !defined(ZERO) && (defined(X86) || defined(AARCH64) || defined(RISCV64) || defined(PPC64) || defined(S390))
|
||||||
ObjectMonitor* monitor = reinterpret_cast<ObjectMonitor*>(get_metadata());
|
return reinterpret_cast<ObjectMonitor*>(get_metadata());
|
||||||
if (monitor != nullptr && monitor->is_being_async_deflated()) {
|
|
||||||
clear_object_monitor_cache();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return monitor;
|
|
||||||
#else
|
#else
|
||||||
// Other platforms do not make use of the cache yet,
|
// Other platforms do not make use of the cache yet,
|
||||||
// and are not as careful with maintaining the invariant
|
// and are not as careful with maintaining the invariant
|
||||||
|
@ -633,7 +633,7 @@ void LightweightSynchronizer::enter_for(Handle obj, BasicLock* lock, JavaThread*
|
|||||||
} else {
|
} else {
|
||||||
do {
|
do {
|
||||||
// It is assumed that enter_for must enter on an object without contention.
|
// It is assumed that enter_for must enter on an object without contention.
|
||||||
monitor = inflate_and_enter(obj(), lock, ObjectSynchronizer::inflate_cause_monitor_enter, locking_thread, current);
|
monitor = inflate_and_enter(obj(), ObjectSynchronizer::inflate_cause_monitor_enter, locking_thread, current);
|
||||||
// But there may still be a race with deflation.
|
// But there may still be a race with deflation.
|
||||||
} while (monitor == nullptr);
|
} while (monitor == nullptr);
|
||||||
}
|
}
|
||||||
@ -689,7 +689,7 @@ void LightweightSynchronizer::enter(Handle obj, BasicLock* lock, JavaThread* cur
|
|||||||
spin_yield.wait();
|
spin_yield.wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectMonitor* monitor = inflate_and_enter(obj(), lock, ObjectSynchronizer::inflate_cause_monitor_enter, current, current);
|
ObjectMonitor* monitor = inflate_and_enter(obj(), ObjectSynchronizer::inflate_cause_monitor_enter, current, current);
|
||||||
if (monitor != nullptr) {
|
if (monitor != nullptr) {
|
||||||
cache_setter.set_monitor(monitor);
|
cache_setter.set_monitor(monitor);
|
||||||
return;
|
return;
|
||||||
@ -703,7 +703,7 @@ void LightweightSynchronizer::enter(Handle obj, BasicLock* lock, JavaThread* cur
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightweightSynchronizer::exit(oop object, BasicLock* lock, JavaThread* current) {
|
void LightweightSynchronizer::exit(oop object, JavaThread* current) {
|
||||||
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
|
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
|
||||||
assert(current == Thread::current(), "must be");
|
assert(current == Thread::current(), "must be");
|
||||||
|
|
||||||
@ -738,18 +738,7 @@ void LightweightSynchronizer::exit(oop object, BasicLock* lock, JavaThread* curr
|
|||||||
|
|
||||||
assert(mark.has_monitor(), "must be");
|
assert(mark.has_monitor(), "must be");
|
||||||
// The monitor exists
|
// The monitor exists
|
||||||
ObjectMonitor* monitor;
|
ObjectMonitor* monitor = ObjectSynchronizer::read_monitor(current, object, mark);
|
||||||
if (UseObjectMonitorTable) {
|
|
||||||
monitor = lock->object_monitor_cache();
|
|
||||||
if (monitor == nullptr) {
|
|
||||||
monitor = current->om_get_from_monitor_cache(object);
|
|
||||||
if (monitor == nullptr) {
|
|
||||||
monitor = get_monitor_from_table(current, object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
monitor = ObjectSynchronizer::read_monitor(mark);
|
|
||||||
}
|
|
||||||
if (monitor->has_anonymous_owner()) {
|
if (monitor->has_anonymous_owner()) {
|
||||||
assert(current->lock_stack().contains(object), "current must have object on its lock stack");
|
assert(current->lock_stack().contains(object), "current must have object on its lock stack");
|
||||||
monitor->set_owner_from_anonymous(current);
|
monitor->set_owner_from_anonymous(current);
|
||||||
@ -988,7 +977,7 @@ ObjectMonitor* LightweightSynchronizer::inflate_fast_locked_object(oop object, O
|
|||||||
return monitor;
|
return monitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectMonitor* LightweightSynchronizer::inflate_and_enter(oop object, BasicLock* lock, ObjectSynchronizer::InflateCause cause, JavaThread* locking_thread, JavaThread* current) {
|
ObjectMonitor* LightweightSynchronizer::inflate_and_enter(oop object, ObjectSynchronizer::InflateCause cause, JavaThread* locking_thread, JavaThread* current) {
|
||||||
assert(LockingMode == LM_LIGHTWEIGHT, "only used for lightweight");
|
assert(LockingMode == LM_LIGHTWEIGHT, "only used for lightweight");
|
||||||
VerifyThreadState vts(locking_thread, current);
|
VerifyThreadState vts(locking_thread, current);
|
||||||
|
|
||||||
@ -1014,20 +1003,18 @@ ObjectMonitor* LightweightSynchronizer::inflate_and_enter(oop object, BasicLock*
|
|||||||
|
|
||||||
NoSafepointVerifier nsv;
|
NoSafepointVerifier nsv;
|
||||||
|
|
||||||
|
// Lightweight monitors require that hash codes are installed first
|
||||||
|
ObjectSynchronizer::FastHashCode(locking_thread, object);
|
||||||
|
|
||||||
// Try to get the monitor from the thread-local cache.
|
// Try to get the monitor from the thread-local cache.
|
||||||
// There's no need to use the cache if we are locking
|
// There's no need to use the cache if we are locking
|
||||||
// on behalf of another thread.
|
// on behalf of another thread.
|
||||||
if (current == locking_thread) {
|
if (current == locking_thread) {
|
||||||
monitor = lock->object_monitor_cache();
|
monitor = current->om_get_from_monitor_cache(object);
|
||||||
if (monitor == nullptr) {
|
|
||||||
monitor = current->om_get_from_monitor_cache(object);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get or create the monitor
|
// Get or create the monitor
|
||||||
if (monitor == nullptr) {
|
if (monitor == nullptr) {
|
||||||
// Lightweight monitors require that hash codes are installed first
|
|
||||||
ObjectSynchronizer::FastHashCode(locking_thread, object);
|
|
||||||
monitor = get_or_insert_monitor(object, current, cause);
|
monitor = get_or_insert_monitor(object, current, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1175,6 +1162,9 @@ bool LightweightSynchronizer::quick_enter(oop obj, BasicLock* lock, JavaThread*
|
|||||||
assert(obj != nullptr, "must be");
|
assert(obj != nullptr, "must be");
|
||||||
NoSafepointVerifier nsv;
|
NoSafepointVerifier nsv;
|
||||||
|
|
||||||
|
// If quick_enter succeeds with entering, the cache should be in a valid initialized state.
|
||||||
|
CacheSetter cache_setter(current, lock);
|
||||||
|
|
||||||
LockStack& lock_stack = current->lock_stack();
|
LockStack& lock_stack = current->lock_stack();
|
||||||
if (lock_stack.is_full()) {
|
if (lock_stack.is_full()) {
|
||||||
// Always go into runtime if the lock stack is full.
|
// Always go into runtime if the lock stack is full.
|
||||||
@ -1201,28 +1191,17 @@ bool LightweightSynchronizer::quick_enter(oop obj, BasicLock* lock, JavaThread*
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mark.has_monitor()) {
|
if (mark.has_monitor()) {
|
||||||
ObjectMonitor* monitor;
|
ObjectMonitor* const monitor = UseObjectMonitorTable ? current->om_get_from_monitor_cache(obj) :
|
||||||
if (UseObjectMonitorTable) {
|
ObjectSynchronizer::read_monitor(mark);
|
||||||
// C2 fast-path may have put the monitor in the cache in the BasicLock.
|
|
||||||
monitor = lock->object_monitor_cache();
|
|
||||||
if (monitor == nullptr) {
|
|
||||||
// Otherwise look up the monitor in the thread's OMCache.
|
|
||||||
monitor = current->om_get_from_monitor_cache(obj);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
monitor = ObjectSynchronizer::read_monitor(mark);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (monitor == nullptr) {
|
if (monitor == nullptr) {
|
||||||
// Take the slow-path on a cache miss.
|
// Take the slow-path on a cache miss.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UseObjectMonitorTable) {
|
if (monitor->try_enter(current)) {
|
||||||
lock->set_object_monitor_cache(monitor);
|
// ObjectMonitor enter successful.
|
||||||
}
|
cache_setter.set_monitor(monitor);
|
||||||
|
|
||||||
if (monitor->spin_enter(current)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,12 +61,12 @@ class LightweightSynchronizer : AllStatic {
|
|||||||
public:
|
public:
|
||||||
static void enter_for(Handle obj, BasicLock* lock, JavaThread* locking_thread);
|
static void enter_for(Handle obj, BasicLock* lock, JavaThread* locking_thread);
|
||||||
static void enter(Handle obj, BasicLock* lock, JavaThread* current);
|
static void enter(Handle obj, BasicLock* lock, JavaThread* current);
|
||||||
static void exit(oop object, BasicLock* lock, JavaThread* current);
|
static void exit(oop object, JavaThread* current);
|
||||||
|
|
||||||
static ObjectMonitor* inflate_into_object_header(oop object, ObjectSynchronizer::InflateCause cause, JavaThread* locking_thread, Thread* current);
|
static ObjectMonitor* inflate_into_object_header(oop object, ObjectSynchronizer::InflateCause cause, JavaThread* locking_thread, Thread* current);
|
||||||
static ObjectMonitor* inflate_locked_or_imse(oop object, ObjectSynchronizer::InflateCause cause, TRAPS);
|
static ObjectMonitor* inflate_locked_or_imse(oop object, ObjectSynchronizer::InflateCause cause, TRAPS);
|
||||||
static ObjectMonitor* inflate_fast_locked_object(oop object, ObjectSynchronizer::InflateCause cause, JavaThread* locking_thread, JavaThread* current);
|
static ObjectMonitor* inflate_fast_locked_object(oop object, ObjectSynchronizer::InflateCause cause, JavaThread* locking_thread, JavaThread* current);
|
||||||
static ObjectMonitor* inflate_and_enter(oop object, BasicLock* lock, ObjectSynchronizer::InflateCause cause, JavaThread* locking_thread, JavaThread* current);
|
static ObjectMonitor* inflate_and_enter(oop object, ObjectSynchronizer::InflateCause cause, JavaThread* locking_thread, JavaThread* current);
|
||||||
|
|
||||||
static void deflate_monitor(Thread* current, oop obj, ObjectMonitor* monitor);
|
static void deflate_monitor(Thread* current, oop obj, ObjectMonitor* monitor);
|
||||||
|
|
||||||
|
@ -148,7 +148,6 @@ class ObjectWaiter : public CHeapObj<mtThread> {
|
|||||||
#define OM_CACHE_LINE_SIZE DEFAULT_CACHE_LINE_SIZE
|
#define OM_CACHE_LINE_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||||
|
|
||||||
class ObjectMonitor : public CHeapObj<mtObjectMonitor> {
|
class ObjectMonitor : public CHeapObj<mtObjectMonitor> {
|
||||||
friend class LightweightSynchronizer;
|
|
||||||
friend class ObjectSynchronizer;
|
friend class ObjectSynchronizer;
|
||||||
friend class ObjectWaiter;
|
friend class ObjectWaiter;
|
||||||
friend class VMStructs;
|
friend class VMStructs;
|
||||||
|
@ -678,8 +678,7 @@ void ObjectSynchronizer::jni_enter(Handle obj, JavaThread* current) {
|
|||||||
ObjectMonitor* monitor;
|
ObjectMonitor* monitor;
|
||||||
bool entered;
|
bool entered;
|
||||||
if (LockingMode == LM_LIGHTWEIGHT) {
|
if (LockingMode == LM_LIGHTWEIGHT) {
|
||||||
BasicLock lock;
|
entered = LightweightSynchronizer::inflate_and_enter(obj(), inflate_cause_jni_enter, current, current) != nullptr;
|
||||||
entered = LightweightSynchronizer::inflate_and_enter(obj(), &lock, inflate_cause_jni_enter, current, current) != nullptr;
|
|
||||||
} else {
|
} else {
|
||||||
monitor = inflate(current, obj(), inflate_cause_jni_enter);
|
monitor = inflate(current, obj(), inflate_cause_jni_enter);
|
||||||
entered = monitor->enter(current);
|
entered = monitor->enter(current);
|
||||||
|
@ -72,7 +72,7 @@ inline void ObjectSynchronizer::exit(oop object, BasicLock* lock, JavaThread* cu
|
|||||||
current->dec_held_monitor_count();
|
current->dec_held_monitor_count();
|
||||||
|
|
||||||
if (LockingMode == LM_LIGHTWEIGHT) {
|
if (LockingMode == LM_LIGHTWEIGHT) {
|
||||||
LightweightSynchronizer::exit(object, lock, current);
|
LightweightSynchronizer::exit(object, current);
|
||||||
} else {
|
} else {
|
||||||
exit_legacy(object, lock, current);
|
exit_legacy(object, lock, current);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user