1 /* 2 * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_RUNTIME_OBJECTMONITOR_INLINE_HPP 26 #define SHARE_RUNTIME_OBJECTMONITOR_INLINE_HPP 27 28 #include "runtime/objectMonitor.hpp" 29 30 #include "classfile/vmSymbols.hpp" 31 #include "logging/log.hpp" 32 #include "oops/access.inline.hpp" 33 #include "oops/markWord.hpp" 34 #include "runtime/atomic.hpp" 35 #include "runtime/globals.hpp" 36 #include "runtime/javaThread.inline.hpp" 37 #include "runtime/lockStack.inline.hpp" 38 #include "runtime/synchronizer.hpp" 39 #include "runtime/threadIdentifier.hpp" 40 #include "utilities/checkedCast.hpp" 41 #include "utilities/globalDefinitions.hpp" 42 43 inline int64_t ObjectMonitor::owner_id_from(JavaThread* thread) { 44 return thread->monitor_owner_id(); 45 } 46 47 inline int64_t ObjectMonitor::owner_id_from(oop vthread) { 48 int64_t id = java_lang_Thread::thread_id(vthread); 49 ThreadIdentifier::verify_id(id); 50 return id; 51 } 52 53 inline bool ObjectMonitor::is_entered(JavaThread* current) const { 54 if (has_anonymous_owner()) { 55 if (LockingMode == LM_LIGHTWEIGHT) { 56 return current->lock_stack().contains(object()); 57 } else { 58 return current->is_lock_owned((address)stack_locker()); 59 } 60 } else { 61 return has_owner(current); 62 } 63 return false; 64 } 65 66 inline uintptr_t ObjectMonitor::metadata() const { 67 return Atomic::load(&_metadata); 68 } 69 70 inline void ObjectMonitor::set_metadata(uintptr_t value) { 71 Atomic::store(&_metadata, value); 72 } 73 74 inline volatile uintptr_t* ObjectMonitor::metadata_addr() { 75 STATIC_ASSERT(std::is_standard_layout<ObjectMonitor>::value); 76 STATIC_ASSERT(offsetof(ObjectMonitor, _metadata) == 0); 77 return &_metadata; 78 } 79 80 inline markWord ObjectMonitor::header() const { 81 assert(!UseObjectMonitorTable, "Lightweight locking with OM table does not use header"); 82 return markWord(metadata()); 83 } 84 85 inline void ObjectMonitor::set_header(markWord hdr) { 86 assert(!UseObjectMonitorTable, "Lightweight locking with OM table does not use header"); 87 set_metadata(hdr.value()); 88 } 89 90 inline intptr_t ObjectMonitor::hash() const { 91 assert(UseObjectMonitorTable, "Only used by lightweight locking with OM table"); 92 return metadata(); 93 } 94 95 inline void ObjectMonitor::set_hash(intptr_t hash) { 96 assert(UseObjectMonitorTable, "Only used by lightweight locking with OM table"); 97 set_metadata(hash); 98 } 99 100 inline int ObjectMonitor::waiters() const { 101 return _waiters; 102 } 103 104 inline bool ObjectMonitor::has_owner() const { 105 int64_t owner = owner_raw(); 106 return owner != NO_OWNER && owner != DEFLATER_MARKER; 107 } 108 109 // Returns NO_OWNER if DEFLATER_MARKER is observed. 110 inline int64_t ObjectMonitor::owner() const { 111 int64_t owner = owner_raw(); 112 return owner != DEFLATER_MARKER ? owner : NO_OWNER; 113 } 114 115 inline int64_t ObjectMonitor::owner_raw() const { 116 return Atomic::load(&_owner); 117 } 118 119 inline BasicLock* ObjectMonitor::stack_locker() const { 120 return Atomic::load(&_stack_locker); 121 } 122 123 inline void ObjectMonitor::set_stack_locker(BasicLock* locker) { 124 Atomic::store(&_stack_locker, locker); 125 } 126 127 // Returns true if owner field == DEFLATER_MARKER and false otherwise. 128 inline bool ObjectMonitor::owner_is_DEFLATER_MARKER() const { 129 return owner_raw() == DEFLATER_MARKER; 130 } 131 132 // Returns true if 'this' is being async deflated and false otherwise. 133 inline bool ObjectMonitor::is_being_async_deflated() { 134 return contentions() < 0; 135 } 136 137 // Return number of threads contending for this monitor. 138 inline int ObjectMonitor::contentions() const { 139 return Atomic::load(&_contentions); 140 } 141 142 // Add value to the contentions field. 143 inline void ObjectMonitor::add_to_contentions(int value) { 144 Atomic::add(&_contentions, value); 145 } 146 147 inline void ObjectMonitor::inc_unmounted_vthreads() { 148 assert(_unmounted_vthreads >= 0, ""); 149 Atomic::inc(&_unmounted_vthreads, memory_order_relaxed); 150 } 151 152 inline void ObjectMonitor::dec_unmounted_vthreads() { 153 assert(_unmounted_vthreads > 0, ""); 154 Atomic::dec(&_unmounted_vthreads, memory_order_relaxed); 155 } 156 157 inline bool ObjectMonitor::has_unmounted_vthreads() const { 158 assert(_unmounted_vthreads >= 0, ""); 159 return Atomic::load(&_unmounted_vthreads) > 0; 160 } 161 162 inline void ObjectMonitor::set_recursions(size_t recursions) { 163 assert(_recursions == 0, "must be"); 164 assert(has_owner(), "must be owned"); 165 _recursions = checked_cast<intx>(recursions); 166 } 167 168 inline void ObjectMonitor::increment_recursions(JavaThread* current) { 169 assert(has_owner(current), "must be the owner"); 170 _recursions++; 171 } 172 173 // Clear _owner field; current value must match old_value. 174 inline void ObjectMonitor::release_clear_owner(JavaThread* old_owner) { 175 int64_t old_value = owner_id_from(old_owner); 176 #ifdef ASSERT 177 int64_t prev = Atomic::load(&_owner); 178 assert(prev == old_value, "unexpected prev owner=" INT64_FORMAT 179 ", expected=" INT64_FORMAT, prev, old_value); 180 #endif 181 Atomic::release_store(&_owner, NO_OWNER); 182 log_trace(monitorinflation, owner)("release_clear_owner(): mid=" 183 INTPTR_FORMAT ", old_value=" INT64_FORMAT, 184 p2i(this), old_value); 185 } 186 187 // Simply set _owner field to new_value; current value must match old_value. 188 // (Simple means no memory sync needed.) 189 inline void ObjectMonitor::set_owner_from_raw(int64_t old_value, int64_t new_value) { 190 #ifdef ASSERT 191 int64_t prev = Atomic::load(&_owner); 192 assert((int64_t)prev < ThreadIdentifier::current(), "must be reasonable"); 193 assert(prev == old_value, "unexpected prev owner=" INT64_FORMAT 194 ", expected=" INT64_FORMAT, prev, old_value); 195 #endif 196 Atomic::store(&_owner, new_value); 197 log_trace(monitorinflation, owner)("set_owner_from(): mid=" 198 INTPTR_FORMAT ", old_value=" INT64_FORMAT 199 ", new_value=" INT64_FORMAT, p2i(this), 200 old_value, new_value); 201 } 202 203 inline void ObjectMonitor::set_owner_from(int64_t old_value, JavaThread* current) { 204 set_owner_from_raw(old_value, owner_id_from(current)); 205 } 206 207 // Try to set _owner field to new_value if the current value matches 208 // old_value. Otherwise, does not change the _owner field. Returns 209 // the prior value of the _owner field. 210 inline int64_t ObjectMonitor::try_set_owner_from_raw(int64_t old_value, int64_t new_value) { 211 assert((int64_t)new_value < ThreadIdentifier::current(), "must be reasonable"); 212 int64_t prev = Atomic::cmpxchg(&_owner, old_value, new_value); 213 if (prev == old_value) { 214 log_trace(monitorinflation, owner)("try_set_owner_from(): mid=" 215 INTPTR_FORMAT ", prev=" INT64_FORMAT 216 ", new=" INT64_FORMAT, p2i(this), 217 prev, new_value); 218 } 219 return prev; 220 } 221 222 inline int64_t ObjectMonitor::try_set_owner_from(int64_t old_value, JavaThread* current) { 223 return try_set_owner_from_raw(old_value, owner_id_from(current)); 224 } 225 226 inline bool ObjectMonitor::has_successor() const { 227 return Atomic::load(&_succ) != NO_OWNER; 228 } 229 230 inline bool ObjectMonitor::has_successor(JavaThread* thread) const { 231 return owner_id_from(thread) == Atomic::load(&_succ); 232 } 233 234 inline void ObjectMonitor::set_successor(JavaThread* thread) { 235 Atomic::store(&_succ, owner_id_from(thread)); 236 } 237 238 inline void ObjectMonitor::set_successor(oop vthread) { 239 Atomic::store(&_succ, java_lang_Thread::thread_id(vthread)); 240 } 241 242 inline void ObjectMonitor::clear_successor() { 243 Atomic::store(&_succ, NO_OWNER); 244 } 245 246 inline int64_t ObjectMonitor::successor() const { 247 return Atomic::load(&_succ); 248 } 249 250 // The _next_om field can be concurrently read and modified so we 251 // use Atomic operations to disable compiler optimizations that 252 // might try to elide loading and/or storing this field. 253 254 // Simply get _next_om field. 255 inline ObjectMonitor* ObjectMonitor::next_om() const { 256 return Atomic::load(&_next_om); 257 } 258 259 // Simply set _next_om field to new_value. 260 inline void ObjectMonitor::set_next_om(ObjectMonitor* new_value) { 261 Atomic::store(&_next_om, new_value); 262 } 263 264 // Block out deflation. 265 inline ObjectMonitorContentionMark::ObjectMonitorContentionMark(ObjectMonitor* monitor) 266 : _monitor(monitor), _extended(false) { 267 // Contentions is incremented to a positive value as part of the 268 // contended enter protocol, which prevents the deflater thread from 269 // winning the last part of the 2-part async deflation 270 // protocol. See: ObjectMonitor::deflate_monitor() and 271 // ObjectMonitor::try_lock_with_contention_mark(). 272 _monitor->add_to_contentions(1); 273 } 274 275 inline ObjectMonitorContentionMark::~ObjectMonitorContentionMark() { 276 // Decrement contentions when the contention mark goes out of 277 // scope. This opens up for deflation, if the contention mark 278 // hasn't been extended. 279 _monitor->add_to_contentions(-1); 280 } 281 282 inline void ObjectMonitorContentionMark::extend() { 283 // Used by ObjectMonitor::try_lock_with_contention_mark() to "extend the 284 // lifetime" of the contention mark. 285 assert(!_extended, "extending twice is probably a bad design"); 286 _monitor->add_to_contentions(1); 287 _extended = true; 288 } 289 290 inline oop ObjectMonitor::object_peek() const { 291 if (_object.is_null()) { 292 return nullptr; 293 } 294 return _object.peek(); 295 } 296 297 inline bool ObjectMonitor::object_is_dead() const { 298 return object_peek() == nullptr; 299 } 300 301 inline bool ObjectMonitor::object_refers_to(oop obj) const { 302 if (_object.is_null()) { 303 return false; 304 } 305 return _object.peek() == obj; 306 } 307 308 inline bool ObjectMonitor::is_jfr_excluded(const Klass* monitor_klass) { 309 assert(monitor_klass != nullptr, "invariant"); 310 NOT_JFR_RETURN_(false); 311 JFR_ONLY(return vmSymbols::jdk_jfr_internal_management_HiddenWait() == monitor_klass->name();) 312 } 313 314 #endif // SHARE_RUNTIME_OBJECTMONITOR_INLINE_HPP