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/atomicAccess.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 return current->lock_stack().contains(object()); 56 } else { 57 return has_owner(current); 58 } 59 return false; 60 } 61 62 inline uintptr_t ObjectMonitor::metadata() const { 63 return AtomicAccess::load(&_metadata); 64 } 65 66 inline void ObjectMonitor::set_metadata(uintptr_t value) { 67 AtomicAccess::store(&_metadata, value); 68 } 69 70 inline volatile uintptr_t* ObjectMonitor::metadata_addr() { 71 STATIC_ASSERT(std::is_standard_layout<ObjectMonitor>::value); 72 STATIC_ASSERT(offsetof(ObjectMonitor, _metadata) == 0); 73 return &_metadata; 74 } 75 76 inline markWord ObjectMonitor::header() const { 77 assert(!UseObjectMonitorTable, "Lightweight locking with OM table does not use header"); 78 return markWord(metadata()); 79 } 80 81 inline void ObjectMonitor::set_header(markWord hdr) { 82 assert(!UseObjectMonitorTable, "Lightweight locking with OM table does not use header"); 83 set_metadata(hdr.value()); 84 } 85 86 inline intptr_t ObjectMonitor::hash() const { 87 assert(UseObjectMonitorTable, "Only used by lightweight locking with OM table"); 88 return metadata(); 89 } 90 91 inline void ObjectMonitor::set_hash(intptr_t hash) { 92 assert(UseObjectMonitorTable, "Only used by lightweight locking with OM table"); 93 set_metadata(hash); 94 } 95 96 inline int ObjectMonitor::waiters() const { 97 return _waiters; 98 } 99 100 inline bool ObjectMonitor::has_owner() const { 101 int64_t owner = owner_raw(); 102 return owner != NO_OWNER && owner != DEFLATER_MARKER; 103 } 104 105 // Returns NO_OWNER if DEFLATER_MARKER is observed. 106 inline int64_t ObjectMonitor::owner() const { 107 int64_t owner = owner_raw(); 108 return owner != DEFLATER_MARKER ? owner : NO_OWNER; 109 } 110 111 inline int64_t ObjectMonitor::owner_raw() const { 112 return AtomicAccess::load(&_owner); 113 } 114 115 // Returns true if owner field == DEFLATER_MARKER and false otherwise. 116 inline bool ObjectMonitor::owner_is_DEFLATER_MARKER() const { 117 return owner_raw() == DEFLATER_MARKER; 118 } 119 120 // Returns true if 'this' is being async deflated and false otherwise. 121 inline bool ObjectMonitor::is_being_async_deflated() { 122 return contentions() < 0; 123 } 124 125 // Return number of threads contending for this monitor. 126 inline int ObjectMonitor::contentions() const { 127 return AtomicAccess::load(&_contentions); 128 } 129 130 // Add value to the contentions field. 131 inline void ObjectMonitor::add_to_contentions(int value) { 132 AtomicAccess::add(&_contentions, value); 133 } 134 135 inline void ObjectMonitor::inc_unmounted_vthreads() { 136 assert(_unmounted_vthreads >= 0, ""); 137 AtomicAccess::inc(&_unmounted_vthreads, memory_order_relaxed); 138 } 139 140 inline void ObjectMonitor::dec_unmounted_vthreads() { 141 assert(_unmounted_vthreads > 0, ""); 142 AtomicAccess::dec(&_unmounted_vthreads, memory_order_relaxed); 143 } 144 145 inline bool ObjectMonitor::has_unmounted_vthreads() const { 146 assert(_unmounted_vthreads >= 0, ""); 147 return AtomicAccess::load(&_unmounted_vthreads) > 0; 148 } 149 150 inline void ObjectMonitor::set_recursions(size_t recursions) { 151 assert(_recursions == 0, "must be"); 152 assert(has_owner(), "must be owned"); 153 _recursions = checked_cast<intx>(recursions); 154 } 155 156 inline void ObjectMonitor::increment_recursions(JavaThread* current) { 157 assert(has_owner(current), "must be the owner"); 158 _recursions++; 159 } 160 161 // Clear _owner field; current value must match old_value. 162 inline void ObjectMonitor::release_clear_owner(JavaThread* old_owner) { 163 int64_t old_value = owner_id_from(old_owner); 164 #ifdef ASSERT 165 int64_t prev = AtomicAccess::load(&_owner); 166 assert(prev == old_value, "unexpected prev owner=" INT64_FORMAT 167 ", expected=" INT64_FORMAT, prev, old_value); 168 #endif 169 AtomicAccess::release_store(&_owner, NO_OWNER); 170 log_trace(monitorinflation, owner)("release_clear_owner(): mid=" 171 INTPTR_FORMAT ", old_value=" INT64_FORMAT, 172 p2i(this), old_value); 173 } 174 175 // Simply set _owner field to new_value; current value must match old_value. 176 // (Simple means no memory sync needed.) 177 inline void ObjectMonitor::set_owner_from_raw(int64_t old_value, int64_t new_value) { 178 #ifdef ASSERT 179 int64_t prev = AtomicAccess::load(&_owner); 180 assert((int64_t)prev < ThreadIdentifier::current(), "must be reasonable"); 181 assert(prev == old_value, "unexpected prev owner=" INT64_FORMAT 182 ", expected=" INT64_FORMAT, prev, old_value); 183 #endif 184 AtomicAccess::store(&_owner, new_value); 185 log_trace(monitorinflation, owner)("set_owner_from(): mid=" 186 INTPTR_FORMAT ", old_value=" INT64_FORMAT 187 ", new_value=" INT64_FORMAT, p2i(this), 188 old_value, new_value); 189 } 190 191 inline void ObjectMonitor::set_owner_from(int64_t old_value, JavaThread* current) { 192 set_owner_from_raw(old_value, owner_id_from(current)); 193 } 194 195 // Try to set _owner field to new_value if the current value matches 196 // old_value. Otherwise, does not change the _owner field. Returns 197 // the prior value of the _owner field. 198 inline int64_t ObjectMonitor::try_set_owner_from_raw(int64_t old_value, int64_t new_value) { 199 assert((int64_t)new_value < ThreadIdentifier::current(), "must be reasonable"); 200 int64_t prev = AtomicAccess::cmpxchg(&_owner, old_value, new_value); 201 if (prev == old_value) { 202 log_trace(monitorinflation, owner)("try_set_owner_from(): mid=" 203 INTPTR_FORMAT ", prev=" INT64_FORMAT 204 ", new=" INT64_FORMAT, p2i(this), 205 prev, new_value); 206 } 207 return prev; 208 } 209 210 inline int64_t ObjectMonitor::try_set_owner_from(int64_t old_value, JavaThread* current) { 211 return try_set_owner_from_raw(old_value, owner_id_from(current)); 212 } 213 214 inline bool ObjectMonitor::has_successor() const { 215 return AtomicAccess::load(&_succ) != NO_OWNER; 216 } 217 218 inline bool ObjectMonitor::has_successor(JavaThread* thread) const { 219 return owner_id_from(thread) == AtomicAccess::load(&_succ); 220 } 221 222 inline void ObjectMonitor::set_successor(JavaThread* thread) { 223 AtomicAccess::store(&_succ, owner_id_from(thread)); 224 } 225 226 inline void ObjectMonitor::set_successor(oop vthread) { 227 AtomicAccess::store(&_succ, java_lang_Thread::thread_id(vthread)); 228 } 229 230 inline void ObjectMonitor::clear_successor() { 231 AtomicAccess::store(&_succ, NO_OWNER); 232 } 233 234 inline int64_t ObjectMonitor::successor() const { 235 return AtomicAccess::load(&_succ); 236 } 237 238 // The _next_om field can be concurrently read and modified so we 239 // use Atomic operations to disable compiler optimizations that 240 // might try to elide loading and/or storing this field. 241 242 // Simply get _next_om field. 243 inline ObjectMonitor* ObjectMonitor::next_om() const { 244 return AtomicAccess::load(&_next_om); 245 } 246 247 // Simply set _next_om field to new_value. 248 inline void ObjectMonitor::set_next_om(ObjectMonitor* new_value) { 249 AtomicAccess::store(&_next_om, new_value); 250 } 251 252 // Block out deflation. 253 inline ObjectMonitorContentionMark::ObjectMonitorContentionMark(ObjectMonitor* monitor) 254 : _monitor(monitor), _extended(false) { 255 // Contentions is incremented to a positive value as part of the 256 // contended enter protocol, which prevents the deflater thread from 257 // winning the last part of the 2-part async deflation 258 // protocol. See: ObjectMonitor::deflate_monitor() and 259 // ObjectMonitor::try_lock_with_contention_mark(). 260 _monitor->add_to_contentions(1); 261 } 262 263 inline ObjectMonitorContentionMark::~ObjectMonitorContentionMark() { 264 // Decrement contentions when the contention mark goes out of 265 // scope. This opens up for deflation, if the contention mark 266 // hasn't been extended. 267 _monitor->add_to_contentions(-1); 268 } 269 270 inline void ObjectMonitorContentionMark::extend() { 271 // Used by ObjectMonitor::try_lock_with_contention_mark() to "extend the 272 // lifetime" of the contention mark. 273 assert(!_extended, "extending twice is probably a bad design"); 274 _monitor->add_to_contentions(1); 275 _extended = true; 276 } 277 278 inline oop ObjectMonitor::object_peek() const { 279 if (_object.is_null()) { 280 return nullptr; 281 } 282 return _object.peek(); 283 } 284 285 inline bool ObjectMonitor::object_is_dead() const { 286 return object_peek() == nullptr; 287 } 288 289 inline bool ObjectMonitor::object_refers_to(oop obj) const { 290 if (_object.is_null()) { 291 return false; 292 } 293 return _object.peek() == obj; 294 } 295 296 inline bool ObjectMonitor::is_jfr_excluded(const Klass* monitor_klass) { 297 assert(monitor_klass != nullptr, "invariant"); 298 NOT_JFR_RETURN_(false); 299 JFR_ONLY(return vmSymbols::jdk_jfr_internal_management_HiddenWait() == monitor_klass->name();) 300 } 301 302 #endif // SHARE_RUNTIME_OBJECTMONITOR_INLINE_HPP