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::set_recursions(size_t recursions) { 148 assert(_recursions == 0, "must be"); 149 assert(has_owner(), "must be owned"); 150 _recursions = checked_cast<intx>(recursions); 151 } 152 153 inline void ObjectMonitor::increment_recursions(JavaThread* current) { 154 assert(has_owner(current), "must be the owner"); 155 _recursions++; 156 } 157 158 // Clear _owner field; current value must match old_value. 159 inline void ObjectMonitor::release_clear_owner(JavaThread* old_owner) { 160 int64_t old_value = owner_id_from(old_owner); 161 #ifdef ASSERT 162 int64_t prev = Atomic::load(&_owner); 163 assert(prev == old_value, "unexpected prev owner=" INT64_FORMAT 164 ", expected=" INT64_FORMAT, prev, old_value); 165 #endif 166 Atomic::release_store(&_owner, NO_OWNER); 167 log_trace(monitorinflation, owner)("release_clear_owner(): mid=" 168 INTPTR_FORMAT ", old_value=" INT64_FORMAT, 169 p2i(this), old_value); 170 } 171 172 // Simply set _owner field to new_value; current value must match old_value. 173 // (Simple means no memory sync needed.) 174 inline void ObjectMonitor::set_owner_from_raw(int64_t old_value, int64_t new_value) { 175 #ifdef ASSERT 176 int64_t prev = Atomic::load(&_owner); 177 assert((int64_t)prev < ThreadIdentifier::current(), "must be reasonable"); 178 assert(prev == old_value, "unexpected prev owner=" INT64_FORMAT 179 ", expected=" INT64_FORMAT, prev, old_value); 180 #endif 181 Atomic::store(&_owner, new_value); 182 log_trace(monitorinflation, owner)("set_owner_from(): mid=" 183 INTPTR_FORMAT ", old_value=" INT64_FORMAT 184 ", new_value=" INT64_FORMAT, p2i(this), 185 old_value, new_value); 186 } 187 188 inline void ObjectMonitor::set_owner_from(int64_t old_value, JavaThread* current) { 189 set_owner_from_raw(old_value, owner_id_from(current)); 190 } 191 192 // Try to set _owner field to new_value if the current value matches 193 // old_value. Otherwise, does not change the _owner field. Returns 194 // the prior value of the _owner field. 195 inline int64_t ObjectMonitor::try_set_owner_from_raw(int64_t old_value, int64_t new_value) { 196 assert((int64_t)new_value < ThreadIdentifier::current(), "must be reasonable"); 197 int64_t prev = Atomic::cmpxchg(&_owner, old_value, new_value); 198 if (prev == old_value) { 199 log_trace(monitorinflation, owner)("try_set_owner_from(): mid=" 200 INTPTR_FORMAT ", prev=" INT64_FORMAT 201 ", new=" INT64_FORMAT, p2i(this), 202 prev, new_value); 203 } 204 return prev; 205 } 206 207 inline int64_t ObjectMonitor::try_set_owner_from(int64_t old_value, JavaThread* current) { 208 return try_set_owner_from_raw(old_value, owner_id_from(current)); 209 } 210 211 inline bool ObjectMonitor::has_successor() const { 212 return Atomic::load(&_succ) != NO_OWNER; 213 } 214 215 inline bool ObjectMonitor::has_successor(JavaThread* thread) const { 216 return owner_id_from(thread) == Atomic::load(&_succ); 217 } 218 219 inline void ObjectMonitor::set_successor(JavaThread* thread) { 220 Atomic::store(&_succ, owner_id_from(thread)); 221 } 222 223 inline void ObjectMonitor::set_successor(oop vthread) { 224 Atomic::store(&_succ, java_lang_Thread::thread_id(vthread)); 225 } 226 227 inline void ObjectMonitor::clear_successor() { 228 Atomic::store(&_succ, NO_OWNER); 229 } 230 231 inline int64_t ObjectMonitor::successor() const { 232 return Atomic::load(&_succ); 233 } 234 235 // The _next_om field can be concurrently read and modified so we 236 // use Atomic operations to disable compiler optimizations that 237 // might try to elide loading and/or storing this field. 238 239 // Simply get _next_om field. 240 inline ObjectMonitor* ObjectMonitor::next_om() const { 241 return Atomic::load(&_next_om); 242 } 243 244 // Simply set _next_om field to new_value. 245 inline void ObjectMonitor::set_next_om(ObjectMonitor* new_value) { 246 Atomic::store(&_next_om, new_value); 247 } 248 249 // Block out deflation. 250 inline ObjectMonitorContentionMark::ObjectMonitorContentionMark(ObjectMonitor* monitor) 251 : _monitor(monitor), _extended(false) { 252 // Contentions is incremented to a positive value as part of the 253 // contended enter protocol, which prevents the deflater thread from 254 // winning the last part of the 2-part async deflation 255 // protocol. See: ObjectMonitor::deflate_monitor() and 256 // ObjectMonitor::try_lock_with_contention_mark(). 257 _monitor->add_to_contentions(1); 258 } 259 260 inline ObjectMonitorContentionMark::~ObjectMonitorContentionMark() { 261 // Decrement contentions when the contention mark goes out of 262 // scope. This opens up for deflation, if the contention mark 263 // hasn't been extended. 264 _monitor->add_to_contentions(-1); 265 } 266 267 inline void ObjectMonitorContentionMark::extend() { 268 // Used by ObjectMonitor::try_lock_with_contention_mark() to "extend the 269 // lifetime" of the contention mark. 270 assert(!_extended, "extending twice is probably a bad design"); 271 _monitor->add_to_contentions(1); 272 _extended = true; 273 } 274 275 inline oop ObjectMonitor::object_peek() const { 276 if (_object.is_null()) { 277 return nullptr; 278 } 279 return _object.peek(); 280 } 281 282 inline bool ObjectMonitor::object_is_dead() const { 283 return object_peek() == nullptr; 284 } 285 286 inline bool ObjectMonitor::object_refers_to(oop obj) const { 287 if (_object.is_null()) { 288 return false; 289 } 290 return _object.peek() == obj; 291 } 292 293 inline bool ObjectMonitor::is_jfr_excluded(const Klass* monitor_klass) { 294 assert(monitor_klass != nullptr, "invariant"); 295 NOT_JFR_RETURN_(false); 296 JFR_ONLY(return vmSymbols::jdk_jfr_internal_management_HiddenWait() == monitor_klass->name();) 297 } 298 299 #endif // SHARE_RUNTIME_OBJECTMONITOR_INLINE_HPP