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