Skip to content

Commit 9ead2b7

Browse files
coleenpxmas92
andcommitted
8354180: Clean up uses of ObjectMonitor caches
Co-authored-by: Axel Boldt-Christmas <[email protected]> Reviewed-by: aboldtch, fbredberg
1 parent cae7a20 commit 9ead2b7

File tree

6 files changed

+41
-33
lines changed

6 files changed

+41
-33
lines changed

src/hotspot/share/runtime/basicLock.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include "runtime/objectMonitor.hpp"
2828
#include "runtime/synchronizer.hpp"
2929

30-
void BasicLock::print_on(outputStream* st, oop owner) {
30+
void BasicLock::print_on(outputStream* st, oop owner) const {
3131
st->print("monitor");
3232
if (UseObjectMonitorTable) {
3333
ObjectMonitor* mon = object_monitor_cache();

src/hotspot/share/runtime/basicLock.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -61,12 +61,12 @@ class BasicLock {
6161
static int displaced_header_offset_in_bytes() { return metadata_offset_in_bytes(); }
6262

6363
// LM_LIGHTWEIGHT
64-
inline ObjectMonitor* object_monitor_cache();
64+
inline ObjectMonitor* object_monitor_cache() const;
6565
inline void clear_object_monitor_cache();
6666
inline void set_object_monitor_cache(ObjectMonitor* mon);
6767
static int object_monitor_cache_offset_in_bytes() { return metadata_offset_in_bytes(); }
6868

69-
void print_on(outputStream* st, oop owner);
69+
void print_on(outputStream* st, oop owner) const;
7070

7171
// move a basic lock (used during deoptimization)
7272
void move_to(oop obj, BasicLock* dest);

src/hotspot/share/runtime/basicLock.inline.hpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -38,15 +38,10 @@ inline void BasicLock::set_displaced_header(markWord header) {
3838
Atomic::store(&_metadata, header.value());
3939
}
4040

41-
inline ObjectMonitor* BasicLock::object_monitor_cache() {
41+
inline ObjectMonitor* BasicLock::object_monitor_cache() const {
4242
assert(UseObjectMonitorTable, "must be");
4343
#if !defined(ZERO) && (defined(X86) || defined(AARCH64) || defined(RISCV64) || defined(PPC64) || defined(S390))
44-
ObjectMonitor* monitor = reinterpret_cast<ObjectMonitor*>(get_metadata());
45-
if (monitor != nullptr && monitor->is_being_async_deflated()) {
46-
clear_object_monitor_cache();
47-
return nullptr;
48-
}
49-
return monitor;
44+
return reinterpret_cast<ObjectMonitor*>(get_metadata());
5045
#else
5146
// Other platforms do not make use of the cache yet,
5247
// and are not as careful with maintaining the invariant

src/hotspot/share/runtime/deoptimization.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,6 +1666,9 @@ bool Deoptimization::relock_objects(JavaThread* thread, GrowableArray<MonitorInf
16661666
// Entering may create an invalid lock stack. Inflate the lock if it
16671667
// was fast_locked to restore the valid lock stack.
16681668
if (UseObjectMonitorTable) {
1669+
// UseObjectMonitorTable expects the BasicLock cache to be either a
1670+
// valid ObjectMonitor* or nullptr. Right now it is garbage, set it
1671+
// to nullptr.
16691672
lock->clear_object_monitor_cache();
16701673
}
16711674
ObjectSynchronizer::enter_for(obj, lock, deoptee_thread);

src/hotspot/share/runtime/lightweightSynchronizer.cpp

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -519,8 +519,12 @@ class LightweightSynchronizer::CacheSetter : StackObj {
519519
// Only use the cache if using the table.
520520
if (UseObjectMonitorTable) {
521521
if (_monitor != nullptr) {
522-
_thread->om_set_monitor_cache(_monitor);
523-
_lock->set_object_monitor_cache(_monitor);
522+
// If the monitor is already in the BasicLock cache then it is most
523+
// likely in the thread cache, do not set it again to avoid reordering.
524+
if (_monitor != _lock->object_monitor_cache()) {
525+
_thread->om_set_monitor_cache(_monitor);
526+
_lock->set_object_monitor_cache(_monitor);
527+
}
524528
} else {
525529
_lock->clear_object_monitor_cache();
526530
}
@@ -534,6 +538,16 @@ class LightweightSynchronizer::CacheSetter : StackObj {
534538

535539
};
536540

541+
// Reads first from the BasicLock cache then from the OMCache in the current thread.
542+
// C2 fast-path may have put the monitor in the cache in the BasicLock.
543+
inline static ObjectMonitor* read_caches(JavaThread* current, BasicLock* lock, oop object) {
544+
ObjectMonitor* monitor = lock->object_monitor_cache();
545+
if (monitor == nullptr) {
546+
monitor = current->om_get_from_monitor_cache(object);
547+
}
548+
return monitor;
549+
}
550+
537551
class LightweightSynchronizer::VerifyThreadState {
538552
bool _no_safepoint;
539553

@@ -615,15 +629,14 @@ bool LightweightSynchronizer::fast_lock_spin_enter(oop obj, LockStack& lock_stac
615629

616630
void LightweightSynchronizer::enter_for(Handle obj, BasicLock* lock, JavaThread* locking_thread) {
617631
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
632+
assert(!UseObjectMonitorTable || lock->object_monitor_cache() == nullptr, "must be cleared");
618633
JavaThread* current = JavaThread::current();
619634
VerifyThreadState vts(locking_thread, current);
620635

621636
if (obj->klass()->is_value_based()) {
622637
ObjectSynchronizer::handle_sync_on_value_based_class(obj, locking_thread);
623638
}
624639

625-
CacheSetter cache_setter(locking_thread, lock);
626-
627640
LockStack& lock_stack = locking_thread->lock_stack();
628641

629642
ObjectMonitor* monitor = nullptr;
@@ -640,7 +653,7 @@ void LightweightSynchronizer::enter_for(Handle obj, BasicLock* lock, JavaThread*
640653
}
641654

642655
assert(monitor != nullptr, "LightweightSynchronizer::enter_for must succeed");
643-
cache_setter.set_monitor(monitor);
656+
assert(!UseObjectMonitorTable || lock->object_monitor_cache() == nullptr, "unused. already cleared");
644657
}
645658

646659
void LightweightSynchronizer::enter(Handle obj, BasicLock* lock, JavaThread* current) {
@@ -741,12 +754,9 @@ void LightweightSynchronizer::exit(oop object, BasicLock* lock, JavaThread* curr
741754
// The monitor exists
742755
ObjectMonitor* monitor;
743756
if (UseObjectMonitorTable) {
744-
monitor = lock->object_monitor_cache();
757+
monitor = read_caches(current, lock, object);
745758
if (monitor == nullptr) {
746-
monitor = current->om_get_from_monitor_cache(object);
747-
if (monitor == nullptr) {
748-
monitor = get_monitor_from_table(current, object);
749-
}
759+
monitor = get_monitor_from_table(current, object);
750760
}
751761
} else {
752762
monitor = ObjectSynchronizer::read_monitor(mark);
@@ -1019,10 +1029,7 @@ ObjectMonitor* LightweightSynchronizer::inflate_and_enter(oop object, BasicLock*
10191029
// There's no need to use the cache if we are locking
10201030
// on behalf of another thread.
10211031
if (current == locking_thread) {
1022-
monitor = lock->object_monitor_cache();
1023-
if (monitor == nullptr) {
1024-
monitor = current->om_get_from_monitor_cache(object);
1025-
}
1032+
monitor = read_caches(current, lock, object);
10261033
}
10271034

10281035
// Get or create the monitor
@@ -1044,6 +1051,9 @@ ObjectMonitor* LightweightSynchronizer::inflate_and_enter(oop object, BasicLock*
10441051
// The MonitorDeflation thread is deflating the monitor. The locking thread
10451052
// must spin until further progress has been made.
10461053

1054+
// Clear the BasicLock cache as it may contain this monitor.
1055+
lock->clear_object_monitor_cache();
1056+
10471057
const markWord mark = object->mark_acquire();
10481058

10491059
if (mark.has_monitor()) {
@@ -1204,12 +1214,7 @@ bool LightweightSynchronizer::quick_enter(oop obj, BasicLock* lock, JavaThread*
12041214
if (mark.has_monitor()) {
12051215
ObjectMonitor* monitor;
12061216
if (UseObjectMonitorTable) {
1207-
// C2 fast-path may have put the monitor in the cache in the BasicLock.
1208-
monitor = lock->object_monitor_cache();
1209-
if (monitor == nullptr) {
1210-
// Otherwise look up the monitor in the thread's OMCache.
1211-
monitor = current->om_get_from_monitor_cache(obj);
1212-
}
1217+
monitor = read_caches(current, lock, obj);
12131218
} else {
12141219
monitor = ObjectSynchronizer::read_monitor(mark);
12151220
}
@@ -1220,6 +1225,11 @@ bool LightweightSynchronizer::quick_enter(oop obj, BasicLock* lock, JavaThread*
12201225
}
12211226

12221227
if (UseObjectMonitorTable) {
1228+
// Set the monitor regardless of success.
1229+
// Either we successfully lock on the monitor, or we retry with the
1230+
// monitor in the slow path. If the monitor gets deflated, it will be
1231+
// cleared, either by the CacheSetter if we fast lock in enter or in
1232+
// inflate_and_enter when we see that the monitor is deflated.
12231233
lock->set_object_monitor_cache(monitor);
12241234
}
12251235

src/hotspot/share/runtime/objectMonitor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2571,7 +2571,7 @@ void ObjectMonitor::print_on(outputStream* st) const {
25712571
st->print("{contentions=0x%08x,waiters=0x%08x"
25722572
",recursions=%zd,owner=" INT64_FORMAT "}",
25732573
contentions(), waiters(), recursions(),
2574-
owner());
2574+
owner_raw());
25752575
}
25762576
void ObjectMonitor::print() const { print_on(tty); }
25772577

0 commit comments

Comments
 (0)