| File: | jdk/src/hotspot/share/runtime/synchronizer.cpp | 
| Warning: | line 112, column 11 Called C++ object pointer is null  | 
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* | ||||||||
| 2 | * Copyright (c) 1998, 2021, 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 | #include "precompiled.hpp" | ||||||||
| 26 | #include "classfile/vmSymbols.hpp" | ||||||||
| 27 | #include "jfr/jfrEvents.hpp" | ||||||||
| 28 | #include "logging/log.hpp" | ||||||||
| 29 | #include "logging/logStream.hpp" | ||||||||
| 30 | #include "memory/allocation.inline.hpp" | ||||||||
| 31 | #include "memory/padded.hpp" | ||||||||
| 32 | #include "memory/resourceArea.hpp" | ||||||||
| 33 | #include "memory/universe.hpp" | ||||||||
| 34 | #include "oops/markWord.hpp" | ||||||||
| 35 | #include "oops/oop.inline.hpp" | ||||||||
| 36 | #include "runtime/atomic.hpp" | ||||||||
| 37 | #include "runtime/handles.inline.hpp" | ||||||||
| 38 | #include "runtime/handshake.hpp" | ||||||||
| 39 | #include "runtime/interfaceSupport.inline.hpp" | ||||||||
| 40 | #include "runtime/mutexLocker.hpp" | ||||||||
| 41 | #include "runtime/objectMonitor.hpp" | ||||||||
| 42 | #include "runtime/objectMonitor.inline.hpp" | ||||||||
| 43 | #include "runtime/os.inline.hpp" | ||||||||
| 44 | #include "runtime/osThread.hpp" | ||||||||
| 45 | #include "runtime/perfData.hpp" | ||||||||
| 46 | #include "runtime/safepointMechanism.inline.hpp" | ||||||||
| 47 | #include "runtime/safepointVerifiers.hpp" | ||||||||
| 48 | #include "runtime/sharedRuntime.hpp" | ||||||||
| 49 | #include "runtime/stubRoutines.hpp" | ||||||||
| 50 | #include "runtime/synchronizer.hpp" | ||||||||
| 51 | #include "runtime/thread.inline.hpp" | ||||||||
| 52 | #include "runtime/timer.hpp" | ||||||||
| 53 | #include "runtime/vframe.hpp" | ||||||||
| 54 | #include "runtime/vmThread.hpp" | ||||||||
| 55 | #include "utilities/align.hpp" | ||||||||
| 56 | #include "utilities/dtrace.hpp" | ||||||||
| 57 | #include "utilities/events.hpp" | ||||||||
| 58 | #include "utilities/preserveException.hpp" | ||||||||
| 59 | |||||||||
| 60 | void MonitorList::add(ObjectMonitor* m) { | ||||||||
| 61 | ObjectMonitor* head; | ||||||||
| 62 | do { | ||||||||
| 63 | head = Atomic::load(&_head); | ||||||||
| 64 | m->set_next_om(head); | ||||||||
| 65 | } while (Atomic::cmpxchg(&_head, head, m) != head); | ||||||||
| 66 | |||||||||
| 67 | size_t count = Atomic::add(&_count, 1u); | ||||||||
| 68 | if (count > max()) { | ||||||||
| 69 | Atomic::inc(&_max); | ||||||||
| 70 | } | ||||||||
| 71 | } | ||||||||
| 72 | |||||||||
| 73 | size_t MonitorList::count() const { | ||||||||
| 74 | return Atomic::load(&_count); | ||||||||
| 75 | } | ||||||||
| 76 | |||||||||
| 77 | size_t MonitorList::max() const { | ||||||||
| 78 | return Atomic::load(&_max); | ||||||||
| 79 | } | ||||||||
| 80 | |||||||||
| 81 | // Walk the in-use list and unlink (at most MonitorDeflationMax) deflated | ||||||||
| 82 | // ObjectMonitors. Returns the number of unlinked ObjectMonitors. | ||||||||
| 83 | size_t MonitorList::unlink_deflated(Thread* current, LogStream* ls, | ||||||||
| 84 | elapsedTimer* timer_p, | ||||||||
| 85 | GrowableArray<ObjectMonitor*>* unlinked_list) { | ||||||||
| 86 | size_t unlinked_count = 0; | ||||||||
| 87 | ObjectMonitor* prev = NULL__null; | ||||||||
| 88 | ObjectMonitor* head = Atomic::load_acquire(&_head); | ||||||||
| 89 | ObjectMonitor* m = head; | ||||||||
| 90 | // The in-use list head can be NULL during the final audit. | ||||||||
| 91 | while (m != NULL__null) { | ||||||||
| 92 | if (m->is_being_async_deflated()) { | ||||||||
| 93 | // Find next live ObjectMonitor. | ||||||||
| 94 | ObjectMonitor* next = m; | ||||||||
| 95 | do { | ||||||||
| 96 | ObjectMonitor* next_next = next->next_om(); | ||||||||
| 97 | unlinked_count++; | ||||||||
| 98 | unlinked_list->append(next); | ||||||||
| 99 | next = next_next; | ||||||||
| 100 | if (unlinked_count >= (size_t)MonitorDeflationMax) { | ||||||||
| 101 | // Reached the max so bail out on the gathering loop. | ||||||||
| 102 | break; | ||||||||
| 103 | } | ||||||||
| 104 | } while (next != NULL__null && next->is_being_async_deflated()); | ||||||||
| 105 |       if (prev
 
  | ||||||||
| 106 | ObjectMonitor* prev_head = Atomic::cmpxchg(&_head, head, next); | ||||||||
| 107 | if (prev_head != head) { | ||||||||
| 108 | // Find new prev ObjectMonitor that just got inserted. | ||||||||
| 109 | for (ObjectMonitor* n = prev_head; n != m; n = n->next_om()) { | ||||||||
| 110 | prev = n; | ||||||||
| 111 | } | ||||||||
| 112 | prev->set_next_om(next); | ||||||||
  | |||||||||
| 113 | } | ||||||||
| 114 | } else { | ||||||||
| 115 | prev->set_next_om(next); | ||||||||
| 116 | } | ||||||||
| 117 | if (unlinked_count >= (size_t)MonitorDeflationMax) { | ||||||||
| 118 | // Reached the max so bail out on the searching loop. | ||||||||
| 119 | break; | ||||||||
| 120 | } | ||||||||
| 121 | m = next; | ||||||||
| 122 | } else { | ||||||||
| 123 | prev = m; | ||||||||
| 124 | m = m->next_om(); | ||||||||
| 125 | } | ||||||||
| 126 | |||||||||
| 127 | if (current->is_Java_thread()) { | ||||||||
| 128 | // A JavaThread must check for a safepoint/handshake and honor it. | ||||||||
| 129 | ObjectSynchronizer::chk_for_block_req(JavaThread::cast(current), "unlinking", | ||||||||
| 130 | "unlinked_count", unlinked_count, | ||||||||
| 131 | ls, timer_p); | ||||||||
| 132 | } | ||||||||
| 133 | } | ||||||||
| 134 | Atomic::sub(&_count, unlinked_count); | ||||||||
| 135 | return unlinked_count; | ||||||||
| 136 | } | ||||||||
| 137 | |||||||||
| 138 | MonitorList::Iterator MonitorList::iterator() const { | ||||||||
| 139 | return Iterator(Atomic::load_acquire(&_head)); | ||||||||
| 140 | } | ||||||||
| 141 | |||||||||
| 142 | ObjectMonitor* MonitorList::Iterator::next() { | ||||||||
| 143 | ObjectMonitor* current = _current; | ||||||||
| 144 | _current = current->next_om(); | ||||||||
| 145 | return current; | ||||||||
| 146 | } | ||||||||
| 147 | |||||||||
| 148 | // The "core" versions of monitor enter and exit reside in this file. | ||||||||
| 149 | // The interpreter and compilers contain specialized transliterated | ||||||||
| 150 | // variants of the enter-exit fast-path operations. See c2_MacroAssembler_x86.cpp | ||||||||
| 151 | // fast_lock(...) for instance. If you make changes here, make sure to modify the | ||||||||
| 152 | // interpreter, and both C1 and C2 fast-path inline locking code emission. | ||||||||
| 153 | // | ||||||||
| 154 | // ----------------------------------------------------------------------------- | ||||||||
| 155 | |||||||||
| 156 | #ifdef DTRACE_ENABLED | ||||||||
| 157 | |||||||||
| 158 | // Only bother with this argument setup if dtrace is available | ||||||||
| 159 | // TODO-FIXME: probes should not fire when caller is _blocked. assert() accordingly. | ||||||||
| 160 | |||||||||
| 161 | #define DTRACE_MONITOR_PROBE_COMMON(obj, thread) \ | ||||||||
| 162 | char* bytes = NULL__null; \ | ||||||||
| 163 | int len = 0; \ | ||||||||
| 164 | jlong jtid = SharedRuntime::get_java_tid(thread); \ | ||||||||
| 165 | Symbol* klassname = obj->klass()->name(); \ | ||||||||
| 166 | if (klassname != NULL__null) { \ | ||||||||
| 167 | bytes = (char*)klassname->bytes(); \ | ||||||||
| 168 | len = klassname->utf8_length(); \ | ||||||||
| 169 | } | ||||||||
| 170 | |||||||||
| 171 | #define DTRACE_MONITOR_WAIT_PROBE(monitor, obj, thread, millis){;} \ | ||||||||
| 172 | { \ | ||||||||
| 173 | if (DTraceMonitorProbes) { \ | ||||||||
| 174 | DTRACE_MONITOR_PROBE_COMMON(obj, thread); \ | ||||||||
| 175 | HOTSPOT_MONITOR_WAIT(jtid, \ | ||||||||
| 176 | (uintptr_t)(monitor), bytes, len, (millis)); \ | ||||||||
| 177 | } \ | ||||||||
| 178 | } | ||||||||
| 179 | |||||||||
| 180 | #define HOTSPOT_MONITOR_PROBE_notify HOTSPOT_MONITOR_NOTIFY | ||||||||
| 181 | #define HOTSPOT_MONITOR_PROBE_notifyAll HOTSPOT_MONITOR_NOTIFYALL | ||||||||
| 182 | #define HOTSPOT_MONITOR_PROBE_waited HOTSPOT_MONITOR_WAITED | ||||||||
| 183 | |||||||||
| 184 | #define DTRACE_MONITOR_PROBE(probe, monitor, obj, thread){;} \ | ||||||||
| 185 | { \ | ||||||||
| 186 | if (DTraceMonitorProbes) { \ | ||||||||
| 187 | DTRACE_MONITOR_PROBE_COMMON(obj, thread); \ | ||||||||
| 188 | HOTSPOT_MONITOR_PROBE_##probe(jtid, /* probe = waited */ \ | ||||||||
| 189 | (uintptr_t)(monitor), bytes, len); \ | ||||||||
| 190 | } \ | ||||||||
| 191 | } | ||||||||
| 192 | |||||||||
| 193 | #else // ndef DTRACE_ENABLED | ||||||||
| 194 | |||||||||
| 195 | #define DTRACE_MONITOR_WAIT_PROBE(obj, thread, millis, mon){;} {;} | ||||||||
| 196 | #define DTRACE_MONITOR_PROBE(probe, obj, thread, mon){;} {;} | ||||||||
| 197 | |||||||||
| 198 | #endif // ndef DTRACE_ENABLED | ||||||||
| 199 | |||||||||
| 200 | // This exists only as a workaround of dtrace bug 6254741 | ||||||||
| 201 | int dtrace_waited_probe(ObjectMonitor* monitor, Handle obj, Thread* thr) { | ||||||||
| 202 | DTRACE_MONITOR_PROBE(waited, monitor, obj(), thr){;}; | ||||||||
| 203 | return 0; | ||||||||
| 204 | } | ||||||||
| 205 | |||||||||
| 206 | static const int NINFLATIONLOCKS = 256; | ||||||||
| 207 | static os::PlatformMutex* gInflationLocks[NINFLATIONLOCKS]; | ||||||||
| 208 | |||||||||
| 209 | void ObjectSynchronizer::initialize() { | ||||||||
| 210 | for (int i = 0; i < NINFLATIONLOCKS; i++) { | ||||||||
| 211 | gInflationLocks[i] = new os::PlatformMutex(); | ||||||||
| 212 | } | ||||||||
| 213 | // Start the ceiling with the estimate for one thread. | ||||||||
| 214 | set_in_use_list_ceiling(AvgMonitorsPerThreadEstimate); | ||||||||
| 215 | } | ||||||||
| 216 | |||||||||
| 217 | MonitorList ObjectSynchronizer::_in_use_list; | ||||||||
| 218 | // monitors_used_above_threshold() policy is as follows: | ||||||||
| 219 | // | ||||||||
| 220 | // The ratio of the current _in_use_list count to the ceiling is used | ||||||||
| 221 | // to determine if we are above MonitorUsedDeflationThreshold and need | ||||||||
| 222 | // to do an async monitor deflation cycle. The ceiling is increased by | ||||||||
| 223 | // AvgMonitorsPerThreadEstimate when a thread is added to the system | ||||||||
| 224 | // and is decreased by AvgMonitorsPerThreadEstimate when a thread is | ||||||||
| 225 | // removed from the system. | ||||||||
| 226 | // | ||||||||
| 227 | // Note: If the _in_use_list max exceeds the ceiling, then | ||||||||
| 228 | // monitors_used_above_threshold() will use the in_use_list max instead | ||||||||
| 229 | // of the thread count derived ceiling because we have used more | ||||||||
| 230 | // ObjectMonitors than the estimated average. | ||||||||
| 231 | // | ||||||||
| 232 | // Note: If deflate_idle_monitors() has NoAsyncDeflationProgressMax | ||||||||
| 233 | // no-progress async monitor deflation cycles in a row, then the ceiling | ||||||||
| 234 | // is adjusted upwards by monitors_used_above_threshold(). | ||||||||
| 235 | // | ||||||||
| 236 | // Start the ceiling with the estimate for one thread in initialize() | ||||||||
| 237 | // which is called after cmd line options are processed. | ||||||||
| 238 | static size_t _in_use_list_ceiling = 0; | ||||||||
| 239 | bool volatile ObjectSynchronizer::_is_async_deflation_requested = false; | ||||||||
| 240 | bool volatile ObjectSynchronizer::_is_final_audit = false; | ||||||||
| 241 | jlong ObjectSynchronizer::_last_async_deflation_time_ns = 0; | ||||||||
| 242 | static uintx _no_progress_cnt = 0; | ||||||||
| 243 | |||||||||
| 244 | // =====================> Quick functions | ||||||||
| 245 | |||||||||
| 246 | // The quick_* forms are special fast-path variants used to improve | ||||||||
| 247 | // performance. In the simplest case, a "quick_*" implementation could | ||||||||
| 248 | // simply return false, in which case the caller will perform the necessary | ||||||||
| 249 | // state transitions and call the slow-path form. | ||||||||
| 250 | // The fast-path is designed to handle frequently arising cases in an efficient | ||||||||
| 251 | // manner and is just a degenerate "optimistic" variant of the slow-path. | ||||||||
| 252 | // returns true -- to indicate the call was satisfied. | ||||||||
| 253 | // returns false -- to indicate the call needs the services of the slow-path. | ||||||||
| 254 | // A no-loitering ordinance is in effect for code in the quick_* family | ||||||||
| 255 | // operators: safepoints or indefinite blocking (blocking that might span a | ||||||||
| 256 | // safepoint) are forbidden. Generally the thread_state() is _in_Java upon | ||||||||
| 257 | // entry. | ||||||||
| 258 | // | ||||||||
| 259 | // Consider: An interesting optimization is to have the JIT recognize the | ||||||||
| 260 | // following common idiom: | ||||||||
| 261 | // synchronized (someobj) { .... ; notify(); } | ||||||||
| 262 | // That is, we find a notify() or notifyAll() call that immediately precedes | ||||||||
| 263 | // the monitorexit operation. In that case the JIT could fuse the operations | ||||||||
| 264 | // into a single notifyAndExit() runtime primitive. | ||||||||
| 265 | |||||||||
| 266 | bool ObjectSynchronizer::quick_notify(oopDesc* obj, JavaThread* current, bool all) { | ||||||||
| 267 |   assert(current->thread_state() == _thread_in_Java, "invariant")do { if (!(current->thread_state() == _thread_in_Java)) { ( *g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 267, "assert(" "current->thread_state() == _thread_in_Java" ") failed", "invariant"); ::breakpoint(); } } while (0);  | ||||||||
| 268 | NoSafepointVerifier nsv; | ||||||||
| 269 | if (obj == NULL__null) return false; // slow-path for invalid obj | ||||||||
| 270 | const markWord mark = obj->mark(); | ||||||||
| 271 | |||||||||
| 272 | if (mark.has_locker() && current->is_lock_owned((address)mark.locker())) { | ||||||||
| 273 | // Degenerate notify | ||||||||
| 274 | // stack-locked by caller so by definition the implied waitset is empty. | ||||||||
| 275 | return true; | ||||||||
| 276 | } | ||||||||
| 277 | |||||||||
| 278 | if (mark.has_monitor()) { | ||||||||
| 279 | ObjectMonitor* const mon = mark.monitor(); | ||||||||
| 280 |     assert(mon->object() == oop(obj), "invariant")do { if (!(mon->object() == oop(obj))) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 280, "assert(" "mon->object() == oop(obj)" ") failed", "invariant" ); ::breakpoint(); } } while (0);  | ||||||||
| 281 | if (mon->owner() != current) return false; // slow-path for IMS exception | ||||||||
| 282 | |||||||||
| 283 | if (mon->first_waiter() != NULL__null) { | ||||||||
| 284 | // We have one or more waiters. Since this is an inflated monitor | ||||||||
| 285 | // that we own, we can transfer one or more threads from the waitset | ||||||||
| 286 | // to the entrylist here and now, avoiding the slow-path. | ||||||||
| 287 | if (all) { | ||||||||
| 288 | DTRACE_MONITOR_PROBE(notifyAll, mon, obj, current){;}; | ||||||||
| 289 | } else { | ||||||||
| 290 | DTRACE_MONITOR_PROBE(notify, mon, obj, current){;}; | ||||||||
| 291 | } | ||||||||
| 292 | int free_count = 0; | ||||||||
| 293 | do { | ||||||||
| 294 | mon->INotify(current); | ||||||||
| 295 | ++free_count; | ||||||||
| 296 | } while (mon->first_waiter() != NULL__null && all); | ||||||||
| 297 |       OM_PERFDATA_OP(Notifications, inc(free_count))do { if (ObjectMonitor::_sync_Notifications != __null && PerfDataManager::has_PerfData()) { ObjectMonitor::_sync_Notifications ->inc(free_count); } } while (0);  | ||||||||
| 298 | } | ||||||||
| 299 | return true; | ||||||||
| 300 | } | ||||||||
| 301 | |||||||||
| 302 | // other IMS exception states take the slow-path | ||||||||
| 303 | return false; | ||||||||
| 304 | } | ||||||||
| 305 | |||||||||
| 306 | |||||||||
| 307 | // The LockNode emitted directly at the synchronization site would have | ||||||||
| 308 | // been too big if it were to have included support for the cases of inflated | ||||||||
| 309 | // recursive enter and exit, so they go here instead. | ||||||||
| 310 | // Note that we can't safely call AsyncPrintJavaStack() from within | ||||||||
| 311 | // quick_enter() as our thread state remains _in_Java. | ||||||||
| 312 | |||||||||
| 313 | bool ObjectSynchronizer::quick_enter(oop obj, JavaThread* current, | ||||||||
| 314 | BasicLock * lock) { | ||||||||
| 315 |   assert(current->thread_state() == _thread_in_Java, "invariant")do { if (!(current->thread_state() == _thread_in_Java)) { ( *g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 315, "assert(" "current->thread_state() == _thread_in_Java" ") failed", "invariant"); ::breakpoint(); } } while (0);  | ||||||||
| 316 | NoSafepointVerifier nsv; | ||||||||
| 317 | if (obj == NULL__null) return false; // Need to throw NPE | ||||||||
| 318 | |||||||||
| 319 | if (obj->klass()->is_value_based()) { | ||||||||
| 320 | return false; | ||||||||
| 321 | } | ||||||||
| 322 | |||||||||
| 323 | const markWord mark = obj->mark(); | ||||||||
| 324 | |||||||||
| 325 | if (mark.has_monitor()) { | ||||||||
| 326 | ObjectMonitor* const m = mark.monitor(); | ||||||||
| 327 | // An async deflation or GC can race us before we manage to make | ||||||||
| 328 | // the ObjectMonitor busy by setting the owner below. If we detect | ||||||||
| 329 | // that race we just bail out to the slow-path here. | ||||||||
| 330 | if (m->object_peek() == NULL__null) { | ||||||||
| 331 | return false; | ||||||||
| 332 | } | ||||||||
| 333 | JavaThread* const owner = (JavaThread*) m->owner_raw(); | ||||||||
| 334 | |||||||||
| 335 | // Lock contention and Transactional Lock Elision (TLE) diagnostics | ||||||||
| 336 | // and observability | ||||||||
| 337 | // Case: light contention possibly amenable to TLE | ||||||||
| 338 | // Case: TLE inimical operations such as nested/recursive synchronization | ||||||||
| 339 | |||||||||
| 340 | if (owner == current) { | ||||||||
| 341 | m->_recursions++; | ||||||||
| 342 | return true; | ||||||||
| 343 | } | ||||||||
| 344 | |||||||||
| 345 | // This Java Monitor is inflated so obj's header will never be | ||||||||
| 346 | // displaced to this thread's BasicLock. Make the displaced header | ||||||||
| 347 | // non-NULL so this BasicLock is not seen as recursive nor as | ||||||||
| 348 | // being locked. We do this unconditionally so that this thread's | ||||||||
| 349 | // BasicLock cannot be mis-interpreted by any stack walkers. For | ||||||||
| 350 | // performance reasons, stack walkers generally first check for | ||||||||
| 351 | // stack-locking in the object's header, the second check is for | ||||||||
| 352 | // recursive stack-locking in the displaced header in the BasicLock, | ||||||||
| 353 | // and last are the inflated Java Monitor (ObjectMonitor) checks. | ||||||||
| 354 | lock->set_displaced_header(markWord::unused_mark()); | ||||||||
| 355 | |||||||||
| 356 | if (owner == NULL__null && m->try_set_owner_from(NULL__null, current) == NULL__null) { | ||||||||
| 357 |       assert(m->_recursions == 0, "invariant")do { if (!(m->_recursions == 0)) { (*g_assert_poison) = 'X' ;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 357, "assert(" "m->_recursions == 0" ") failed", "invariant" ); ::breakpoint(); } } while (0);  | ||||||||
| 358 | return true; | ||||||||
| 359 | } | ||||||||
| 360 | } | ||||||||
| 361 | |||||||||
| 362 | // Note that we could inflate in quick_enter. | ||||||||
| 363 | // This is likely a useful optimization | ||||||||
| 364 | // Critically, in quick_enter() we must not: | ||||||||
| 365 | // -- block indefinitely, or | ||||||||
| 366 | // -- reach a safepoint | ||||||||
| 367 | |||||||||
| 368 | return false; // revert to slow-path | ||||||||
| 369 | } | ||||||||
| 370 | |||||||||
| 371 | // Handle notifications when synchronizing on value based classes | ||||||||
| 372 | void ObjectSynchronizer::handle_sync_on_value_based_class(Handle obj, JavaThread* current) { | ||||||||
| 373 | frame last_frame = current->last_frame(); | ||||||||
| 374 | bool bcp_was_adjusted = false; | ||||||||
| 375 | // Don't decrement bcp if it points to the frame's first instruction. This happens when | ||||||||
| 376 | // handle_sync_on_value_based_class() is called because of a synchronized method. There | ||||||||
| 377 | // is no actual monitorenter instruction in the byte code in this case. | ||||||||
| 378 | if (last_frame.is_interpreted_frame() && | ||||||||
| 379 | (last_frame.interpreter_frame_method()->code_base() < last_frame.interpreter_frame_bcp())) { | ||||||||
| 380 | // adjust bcp to point back to monitorenter so that we print the correct line numbers | ||||||||
| 381 | last_frame.interpreter_frame_set_bcp(last_frame.interpreter_frame_bcp() - 1); | ||||||||
| 382 | bcp_was_adjusted = true; | ||||||||
| 383 | } | ||||||||
| 384 | |||||||||
| 385 | if (DiagnoseSyncOnValueBasedClasses == FATAL_EXIT) { | ||||||||
| 386 | ResourceMark rm(current); | ||||||||
| 387 | stringStream ss; | ||||||||
| 388 | current->print_stack_on(&ss); | ||||||||
| 389 | char* base = (char*)strstr(ss.base(), "at"); | ||||||||
| 390 | char* newline = (char*)strchr(ss.base(), '\n'); | ||||||||
| 391 | if (newline != NULL__null) { | ||||||||
| 392 | *newline = '\0'; | ||||||||
| 393 | } | ||||||||
| 394 |     fatal("Synchronizing on object " INTPTR_FORMAT " of klass %s %s", p2i(obj()), obj->klass()->external_name(), base)do { (*g_assert_poison) = 'X';; report_fatal(INTERNAL_ERROR, "/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 394, "Synchronizing on object " "0x%016" "l" "x" " of klass %s %s" , p2i(obj()), obj->klass()->external_name(), base); ::breakpoint (); } while (0);  | ||||||||
| 395 | } else { | ||||||||
| 396 |     assert(DiagnoseSyncOnValueBasedClasses == LOG_WARNING, "invalid value for DiagnoseSyncOnValueBasedClasses")do { if (!(DiagnoseSyncOnValueBasedClasses == LOG_WARNING)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 396, "assert(" "DiagnoseSyncOnValueBasedClasses == LOG_WARNING" ") failed", "invalid value for DiagnoseSyncOnValueBasedClasses" ); ::breakpoint(); } } while (0);  | ||||||||
| 397 | ResourceMark rm(current); | ||||||||
| 398 |     Log(valuebasedclasses)LogImpl<(LogTag::_valuebasedclasses), (LogTag::__NO_TAG), ( LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag ::__NO_TAG)> vblog;  | ||||||||
| 399 | |||||||||
| 400 | vblog.info("Synchronizing on object " INTPTR_FORMAT"0x%016" "l" "x" " of klass %s", p2i(obj()), obj->klass()->external_name()); | ||||||||
| 401 | if (current->has_last_Java_frame()) { | ||||||||
| 402 | LogStream info_stream(vblog.info()); | ||||||||
| 403 | current->print_stack_on(&info_stream); | ||||||||
| 404 | } else { | ||||||||
| 405 | vblog.info("Cannot find the last Java frame"); | ||||||||
| 406 | } | ||||||||
| 407 | |||||||||
| 408 | EventSyncOnValueBasedClass event; | ||||||||
| 409 | if (event.should_commit()) { | ||||||||
| 410 | event.set_valueBasedClass(obj->klass()); | ||||||||
| 411 | event.commit(); | ||||||||
| 412 | } | ||||||||
| 413 | } | ||||||||
| 414 | |||||||||
| 415 | if (bcp_was_adjusted) { | ||||||||
| 416 | last_frame.interpreter_frame_set_bcp(last_frame.interpreter_frame_bcp() + 1); | ||||||||
| 417 | } | ||||||||
| 418 | } | ||||||||
| 419 | |||||||||
| 420 | static bool useHeavyMonitors() { | ||||||||
| 421 | #if defined(X86) || defined(AARCH64) || defined(PPC64) | ||||||||
| 422 | return UseHeavyMonitors; | ||||||||
| 423 | #else | ||||||||
| 424 | return false; | ||||||||
| 425 | #endif | ||||||||
| 426 | } | ||||||||
| 427 | |||||||||
| 428 | // ----------------------------------------------------------------------------- | ||||||||
| 429 | // Monitor Enter/Exit | ||||||||
| 430 | // The interpreter and compiler assembly code tries to lock using the fast path | ||||||||
| 431 | // of this algorithm. Make sure to update that code if the following function is | ||||||||
| 432 | // changed. The implementation is extremely sensitive to race condition. Be careful. | ||||||||
| 433 | |||||||||
| 434 | void ObjectSynchronizer::enter(Handle obj, BasicLock* lock, JavaThread* current) { | ||||||||
| 435 | if (obj->klass()->is_value_based()) { | ||||||||
| 436 | handle_sync_on_value_based_class(obj, current); | ||||||||
| 437 | } | ||||||||
| 438 | |||||||||
| 439 | if (!useHeavyMonitors()) { | ||||||||
| 440 | markWord mark = obj->mark(); | ||||||||
| 441 | if (mark.is_neutral()) { | ||||||||
| 442 | // Anticipate successful CAS -- the ST of the displaced mark must | ||||||||
| 443 | // be visible <= the ST performed by the CAS. | ||||||||
| 444 | lock->set_displaced_header(mark); | ||||||||
| 445 | if (mark == obj()->cas_set_mark(markWord::from_pointer(lock), mark)) { | ||||||||
| 446 | return; | ||||||||
| 447 | } | ||||||||
| 448 | // Fall through to inflate() ... | ||||||||
| 449 | } else if (mark.has_locker() && | ||||||||
| 450 | current->is_lock_owned((address)mark.locker())) { | ||||||||
| 451 |       assert(lock != mark.locker(), "must not re-lock the same lock")do { if (!(lock != mark.locker())) { (*g_assert_poison) = 'X' ;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 451, "assert(" "lock != mark.locker()" ") failed", "must not re-lock the same lock" ); ::breakpoint(); } } while (0);  | ||||||||
| 452 |       assert(lock != (BasicLock*)obj->mark().value(), "don't relock with same BasicLock")do { if (!(lock != (BasicLock*)obj->mark().value())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 452, "assert(" "lock != (BasicLock*)obj->mark().value()" ") failed", "don't relock with same BasicLock"); ::breakpoint (); } } while (0);  | ||||||||
| 453 | lock->set_displaced_header(markWord::from_pointer(NULL__null)); | ||||||||
| 454 | return; | ||||||||
| 455 | } | ||||||||
| 456 | |||||||||
| 457 | // The object header will never be displaced to this lock, | ||||||||
| 458 | // so it does not matter what the value is, except that it | ||||||||
| 459 | // must be non-zero to avoid looking like a re-entrant lock, | ||||||||
| 460 | // and must not look locked either. | ||||||||
| 461 | lock->set_displaced_header(markWord::unused_mark()); | ||||||||
| 462 | } else if (VerifyHeavyMonitors) { | ||||||||
| 463 |     guarantee(!obj->mark().has_locker(), "must not be stack-locked")do { if (!(!obj->mark().has_locker())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 463, "guarantee(" "!obj->mark().has_locker()" ") failed" , "must not be stack-locked"); ::breakpoint(); } } while (0);  | ||||||||
| 464 | } | ||||||||
| 465 | |||||||||
| 466 | // An async deflation can race after the inflate() call and before | ||||||||
| 467 | // enter() can make the ObjectMonitor busy. enter() returns false if | ||||||||
| 468 | // we have lost the race to async deflation and we simply try again. | ||||||||
| 469 | while (true) { | ||||||||
| 470 | ObjectMonitor* monitor = inflate(current, obj(), inflate_cause_monitor_enter); | ||||||||
| 471 | if (monitor->enter(current)) { | ||||||||
| 472 | return; | ||||||||
| 473 | } | ||||||||
| 474 | } | ||||||||
| 475 | } | ||||||||
| 476 | |||||||||
| 477 | void ObjectSynchronizer::exit(oop object, BasicLock* lock, JavaThread* current) { | ||||||||
| 478 | if (!useHeavyMonitors()) { | ||||||||
| 479 | markWord mark = object->mark(); | ||||||||
| 480 | |||||||||
| 481 | markWord dhw = lock->displaced_header(); | ||||||||
| 482 | if (dhw.value() == 0) { | ||||||||
| 483 | // If the displaced header is NULL, then this exit matches up with | ||||||||
| 484 | // a recursive enter. No real work to do here except for diagnostics. | ||||||||
| 485 | #ifndef PRODUCT | ||||||||
| 486 | if (mark != markWord::INFLATING()) { | ||||||||
| 487 | // Only do diagnostics if we are not racing an inflation. Simply | ||||||||
| 488 | // exiting a recursive enter of a Java Monitor that is being | ||||||||
| 489 | // inflated is safe; see the has_monitor() comment below. | ||||||||
| 490 |         assert(!mark.is_neutral(), "invariant")do { if (!(!mark.is_neutral())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 490, "assert(" "!mark.is_neutral()" ") failed", "invariant" ); ::breakpoint(); } } while (0);  | ||||||||
| 491 |         assert(!mark.has_locker() ||do { if (!(!mark.has_locker() || current->is_lock_owned((address )mark.locker()))) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 492, "assert(" "!mark.has_locker() || current->is_lock_owned((address)mark.locker())" ") failed", "invariant"); ::breakpoint(); } } while (0)  | ||||||||
| 492 |         current->is_lock_owned((address)mark.locker()), "invariant")do { if (!(!mark.has_locker() || current->is_lock_owned((address )mark.locker()))) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 492, "assert(" "!mark.has_locker() || current->is_lock_owned((address)mark.locker())" ") failed", "invariant"); ::breakpoint(); } } while (0);  | ||||||||
| 493 | if (mark.has_monitor()) { | ||||||||
| 494 | // The BasicLock's displaced_header is marked as a recursive | ||||||||
| 495 | // enter and we have an inflated Java Monitor (ObjectMonitor). | ||||||||
| 496 | // This is a special case where the Java Monitor was inflated | ||||||||
| 497 | // after this thread entered the stack-lock recursively. When a | ||||||||
| 498 | // Java Monitor is inflated, we cannot safely walk the Java | ||||||||
| 499 | // Monitor owner's stack and update the BasicLocks because a | ||||||||
| 500 | // Java Monitor can be asynchronously inflated by a thread that | ||||||||
| 501 | // does not own the Java Monitor. | ||||||||
| 502 | ObjectMonitor* m = mark.monitor(); | ||||||||
| 503 |           assert(m->object()->mark() == mark, "invariant")do { if (!(m->object()->mark() == mark)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 503, "assert(" "m->object()->mark() == mark" ") failed" , "invariant"); ::breakpoint(); } } while (0);  | ||||||||
| 504 |           assert(m->is_entered(current), "invariant")do { if (!(m->is_entered(current))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 504, "assert(" "m->is_entered(current)" ") failed", "invariant" ); ::breakpoint(); } } while (0);  | ||||||||
| 505 | } | ||||||||
| 506 | } | ||||||||
| 507 | #endif | ||||||||
| 508 | return; | ||||||||
| 509 | } | ||||||||
| 510 | |||||||||
| 511 | if (mark == markWord::from_pointer(lock)) { | ||||||||
| 512 | // If the object is stack-locked by the current thread, try to | ||||||||
| 513 | // swing the displaced header from the BasicLock back to the mark. | ||||||||
| 514 |       assert(dhw.is_neutral(), "invariant")do { if (!(dhw.is_neutral())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 514, "assert(" "dhw.is_neutral()" ") failed", "invariant"); ::breakpoint(); } } while (0);  | ||||||||
| 515 | if (object->cas_set_mark(dhw, mark) == mark) { | ||||||||
| 516 | return; | ||||||||
| 517 | } | ||||||||
| 518 | } | ||||||||
| 519 | } else if (VerifyHeavyMonitors) { | ||||||||
| 520 |     guarantee(!object->mark().has_locker(), "must not be stack-locked")do { if (!(!object->mark().has_locker())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 520, "guarantee(" "!object->mark().has_locker()" ") failed" , "must not be stack-locked"); ::breakpoint(); } } while (0);  | ||||||||
| 521 | } | ||||||||
| 522 | |||||||||
| 523 | // We have to take the slow-path of possible inflation and then exit. | ||||||||
| 524 | // The ObjectMonitor* can't be async deflated until ownership is | ||||||||
| 525 | // dropped inside exit() and the ObjectMonitor* must be !is_busy(). | ||||||||
| 526 | ObjectMonitor* monitor = inflate(current, object, inflate_cause_vm_internal); | ||||||||
| 527 | monitor->exit(current); | ||||||||
| 528 | } | ||||||||
| 529 | |||||||||
| 530 | // ----------------------------------------------------------------------------- | ||||||||
| 531 | // Class Loader support to workaround deadlocks on the class loader lock objects | ||||||||
| 532 | // Also used by GC | ||||||||
| 533 | // complete_exit()/reenter() are used to wait on a nested lock | ||||||||
| 534 | // i.e. to give up an outer lock completely and then re-enter | ||||||||
| 535 | // Used when holding nested locks - lock acquisition order: lock1 then lock2 | ||||||||
| 536 | // 1) complete_exit lock1 - saving recursion count | ||||||||
| 537 | // 2) wait on lock2 | ||||||||
| 538 | // 3) when notified on lock2, unlock lock2 | ||||||||
| 539 | // 4) reenter lock1 with original recursion count | ||||||||
| 540 | // 5) lock lock2 | ||||||||
| 541 | // NOTE: must use heavy weight monitor to handle complete_exit/reenter() | ||||||||
| 542 | intx ObjectSynchronizer::complete_exit(Handle obj, JavaThread* current) { | ||||||||
| 543 | // The ObjectMonitor* can't be async deflated until ownership is | ||||||||
| 544 | // dropped inside exit() and the ObjectMonitor* must be !is_busy(). | ||||||||
| 545 | ObjectMonitor* monitor = inflate(current, obj(), inflate_cause_vm_internal); | ||||||||
| 546 | intptr_t ret_code = monitor->complete_exit(current); | ||||||||
| 547 | return ret_code; | ||||||||
| 548 | } | ||||||||
| 549 | |||||||||
| 550 | // NOTE: must use heavy weight monitor to handle complete_exit/reenter() | ||||||||
| 551 | void ObjectSynchronizer::reenter(Handle obj, intx recursions, JavaThread* current) { | ||||||||
| 552 | // An async deflation can race after the inflate() call and before | ||||||||
| 553 | // reenter() -> enter() can make the ObjectMonitor busy. reenter() -> | ||||||||
| 554 | // enter() returns false if we have lost the race to async deflation | ||||||||
| 555 | // and we simply try again. | ||||||||
| 556 | while (true) { | ||||||||
| 557 | ObjectMonitor* monitor = inflate(current, obj(), inflate_cause_vm_internal); | ||||||||
| 558 | if (monitor->reenter(recursions, current)) { | ||||||||
| 559 | return; | ||||||||
| 560 | } | ||||||||
| 561 | } | ||||||||
| 562 | } | ||||||||
| 563 | |||||||||
| 564 | // ----------------------------------------------------------------------------- | ||||||||
| 565 | // JNI locks on java objects | ||||||||
| 566 | // NOTE: must use heavy weight monitor to handle jni monitor enter | ||||||||
| 567 | void ObjectSynchronizer::jni_enter(Handle obj, JavaThread* current) { | ||||||||
| 568 | if (obj->klass()->is_value_based()) { | ||||||||
| 569 | handle_sync_on_value_based_class(obj, current); | ||||||||
| 570 | } | ||||||||
| 571 | |||||||||
| 572 | // the current locking is from JNI instead of Java code | ||||||||
| 573 | current->set_current_pending_monitor_is_from_java(false); | ||||||||
| 574 | // An async deflation can race after the inflate() call and before | ||||||||
| 575 | // enter() can make the ObjectMonitor busy. enter() returns false if | ||||||||
| 576 | // we have lost the race to async deflation and we simply try again. | ||||||||
| 577 | while (true) { | ||||||||
| 578 | ObjectMonitor* monitor = inflate(current, obj(), inflate_cause_jni_enter); | ||||||||
| 579 | if (monitor->enter(current)) { | ||||||||
| 580 | break; | ||||||||
| 581 | } | ||||||||
| 582 | } | ||||||||
| 583 | current->set_current_pending_monitor_is_from_java(true); | ||||||||
| 584 | } | ||||||||
| 585 | |||||||||
| 586 | // NOTE: must use heavy weight monitor to handle jni monitor exit | ||||||||
| 587 | void ObjectSynchronizer::jni_exit(oop obj, TRAPSJavaThread* __the_thread__) { | ||||||||
| 588 | JavaThread* current = THREAD__the_thread__; | ||||||||
| 589 | |||||||||
| 590 | // The ObjectMonitor* can't be async deflated until ownership is | ||||||||
| 591 | // dropped inside exit() and the ObjectMonitor* must be !is_busy(). | ||||||||
| 592 | ObjectMonitor* monitor = inflate(current, obj, inflate_cause_jni_exit); | ||||||||
| 593 | // If this thread has locked the object, exit the monitor. We | ||||||||
| 594 | // intentionally do not use CHECK on check_owner because we must exit the | ||||||||
| 595 | // monitor even if an exception was already pending. | ||||||||
| 596 | if (monitor->check_owner(THREAD__the_thread__)) { | ||||||||
| 597 | monitor->exit(current); | ||||||||
| 598 | } | ||||||||
| 599 | } | ||||||||
| 600 | |||||||||
| 601 | // ----------------------------------------------------------------------------- | ||||||||
| 602 | // Internal VM locks on java objects | ||||||||
| 603 | // standard constructor, allows locking failures | ||||||||
| 604 | ObjectLocker::ObjectLocker(Handle obj, JavaThread* thread) { | ||||||||
| 605 | _thread = thread; | ||||||||
| 606 | _thread->check_for_valid_safepoint_state(); | ||||||||
| 607 | _obj = obj; | ||||||||
| 608 | |||||||||
| 609 | if (_obj() != NULL__null) { | ||||||||
| 610 | ObjectSynchronizer::enter(_obj, &_lock, _thread); | ||||||||
| 611 | } | ||||||||
| 612 | } | ||||||||
| 613 | |||||||||
| 614 | ObjectLocker::~ObjectLocker() { | ||||||||
| 615 | if (_obj() != NULL__null) { | ||||||||
| 616 | ObjectSynchronizer::exit(_obj(), &_lock, _thread); | ||||||||
| 617 | } | ||||||||
| 618 | } | ||||||||
| 619 | |||||||||
| 620 | |||||||||
| 621 | // ----------------------------------------------------------------------------- | ||||||||
| 622 | // Wait/Notify/NotifyAll | ||||||||
| 623 | // NOTE: must use heavy weight monitor to handle wait() | ||||||||
| 624 | int ObjectSynchronizer::wait(Handle obj, jlong millis, TRAPSJavaThread* __the_thread__) { | ||||||||
| 625 | JavaThread* current = THREAD__the_thread__; | ||||||||
| 626 | if (millis < 0) { | ||||||||
| 627 |     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative"){ Exceptions::_throw_msg(__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 627, vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative" ); return 0; };  | ||||||||
| 628 | } | ||||||||
| 629 | // The ObjectMonitor* can't be async deflated because the _waiters | ||||||||
| 630 | // field is incremented before ownership is dropped and decremented | ||||||||
| 631 | // after ownership is regained. | ||||||||
| 632 | ObjectMonitor* monitor = inflate(current, obj(), inflate_cause_wait); | ||||||||
| 633 | |||||||||
| 634 | DTRACE_MONITOR_WAIT_PROBE(monitor, obj(), current, millis){;}; | ||||||||
| 635 | monitor->wait(millis, true, THREAD__the_thread__); // Not CHECK as we need following code | ||||||||
| 636 | |||||||||
| 637 | // This dummy call is in place to get around dtrace bug 6254741. Once | ||||||||
| 638 | // that's fixed we can uncomment the following line, remove the call | ||||||||
| 639 | // and change this function back into a "void" func. | ||||||||
| 640 | // DTRACE_MONITOR_PROBE(waited, monitor, obj(), THREAD); | ||||||||
| 641 | int ret_code = dtrace_waited_probe(monitor, obj, THREAD__the_thread__); | ||||||||
| 642 | return ret_code; | ||||||||
| 643 | } | ||||||||
| 644 | |||||||||
| 645 | // No exception are possible in this case as we only use this internally when locking is | ||||||||
| 646 | // correct and we have to wait until notified - so no interrupts or timeouts. | ||||||||
| 647 | void ObjectSynchronizer::wait_uninterruptibly(Handle obj, JavaThread* current) { | ||||||||
| 648 | // The ObjectMonitor* can't be async deflated because the _waiters | ||||||||
| 649 | // field is incremented before ownership is dropped and decremented | ||||||||
| 650 | // after ownership is regained. | ||||||||
| 651 | ObjectMonitor* monitor = inflate(current, obj(), inflate_cause_wait); | ||||||||
| 652 | monitor->wait(0 /* wait-forever */, false /* not interruptible */, current); | ||||||||
| 653 | } | ||||||||
| 654 | |||||||||
| 655 | void ObjectSynchronizer::notify(Handle obj, TRAPSJavaThread* __the_thread__) { | ||||||||
| 656 | JavaThread* current = THREAD__the_thread__; | ||||||||
| 657 | |||||||||
| 658 | markWord mark = obj->mark(); | ||||||||
| 659 | if (mark.has_locker() && current->is_lock_owned((address)mark.locker())) { | ||||||||
| 660 | // Not inflated so there can't be any waiters to notify. | ||||||||
| 661 | return; | ||||||||
| 662 | } | ||||||||
| 663 | // The ObjectMonitor* can't be async deflated until ownership is | ||||||||
| 664 | // dropped by the calling thread. | ||||||||
| 665 | ObjectMonitor* monitor = inflate(current, obj(), inflate_cause_notify); | ||||||||
| 666 |   monitor->notify(CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0);  | ||||||||
| 667 | } | ||||||||
| 668 | |||||||||
| 669 | // NOTE: see comment of notify() | ||||||||
| 670 | void ObjectSynchronizer::notifyall(Handle obj, TRAPSJavaThread* __the_thread__) { | ||||||||
| 671 | JavaThread* current = THREAD__the_thread__; | ||||||||
| 672 | |||||||||
| 673 | markWord mark = obj->mark(); | ||||||||
| 674 | if (mark.has_locker() && current->is_lock_owned((address)mark.locker())) { | ||||||||
| 675 | // Not inflated so there can't be any waiters to notify. | ||||||||
| 676 | return; | ||||||||
| 677 | } | ||||||||
| 678 | // The ObjectMonitor* can't be async deflated until ownership is | ||||||||
| 679 | // dropped by the calling thread. | ||||||||
| 680 | ObjectMonitor* monitor = inflate(current, obj(), inflate_cause_notify); | ||||||||
| 681 |   monitor->notifyAll(CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0);  | ||||||||
| 682 | } | ||||||||
| 683 | |||||||||
| 684 | // ----------------------------------------------------------------------------- | ||||||||
| 685 | // Hash Code handling | ||||||||
| 686 | |||||||||
| 687 | struct SharedGlobals { | ||||||||
| 688 | char _pad_prefix[OM_CACHE_LINE_SIZE64]; | ||||||||
| 689 | // This is a highly shared mostly-read variable. | ||||||||
| 690 | // To avoid false-sharing it needs to be the sole occupant of a cache line. | ||||||||
| 691 | volatile int stw_random; | ||||||||
| 692 | DEFINE_PAD_MINUS_SIZE(1, OM_CACHE_LINE_SIZE, sizeof(volatile int))char _pad_buf1[(64) - (sizeof(volatile int))]; | ||||||||
| 693 | // Hot RW variable -- Sequester to avoid false-sharing | ||||||||
| 694 | volatile int hc_sequence; | ||||||||
| 695 | DEFINE_PAD_MINUS_SIZE(2, OM_CACHE_LINE_SIZE, sizeof(volatile int))char _pad_buf2[(64) - (sizeof(volatile int))]; | ||||||||
| 696 | }; | ||||||||
| 697 | |||||||||
| 698 | static SharedGlobals GVars; | ||||||||
| 699 | |||||||||
| 700 | static markWord read_stable_mark(oop obj) { | ||||||||
| 701 | markWord mark = obj->mark_acquire(); | ||||||||
| 702 | if (!mark.is_being_inflated()) { | ||||||||
| 703 | return mark; // normal fast-path return | ||||||||
| 704 | } | ||||||||
| 705 | |||||||||
| 706 | int its = 0; | ||||||||
| 707 | for (;;) { | ||||||||
| 708 | markWord mark = obj->mark_acquire(); | ||||||||
| 709 | if (!mark.is_being_inflated()) { | ||||||||
| 710 | return mark; // normal fast-path return | ||||||||
| 711 | } | ||||||||
| 712 | |||||||||
| 713 | // The object is being inflated by some other thread. | ||||||||
| 714 | // The caller of read_stable_mark() must wait for inflation to complete. | ||||||||
| 715 | // Avoid live-lock. | ||||||||
| 716 | |||||||||
| 717 | ++its; | ||||||||
| 718 | if (its > 10000 || !os::is_MP()) { | ||||||||
| 719 | if (its & 1) { | ||||||||
| 720 | os::naked_yield(); | ||||||||
| 721 | } else { | ||||||||
| 722 | // Note that the following code attenuates the livelock problem but is not | ||||||||
| 723 | // a complete remedy. A more complete solution would require that the inflating | ||||||||
| 724 | // thread hold the associated inflation lock. The following code simply restricts | ||||||||
| 725 | // the number of spinners to at most one. We'll have N-2 threads blocked | ||||||||
| 726 | // on the inflationlock, 1 thread holding the inflation lock and using | ||||||||
| 727 | // a yield/park strategy, and 1 thread in the midst of inflation. | ||||||||
| 728 | // A more refined approach would be to change the encoding of INFLATING | ||||||||
| 729 | // to allow encapsulation of a native thread pointer. Threads waiting for | ||||||||
| 730 | // inflation to complete would use CAS to push themselves onto a singly linked | ||||||||
| 731 | // list rooted at the markword. Once enqueued, they'd loop, checking a per-thread flag | ||||||||
| 732 | // and calling park(). When inflation was complete the thread that accomplished inflation | ||||||||
| 733 | // would detach the list and set the markword to inflated with a single CAS and | ||||||||
| 734 | // then for each thread on the list, set the flag and unpark() the thread. | ||||||||
| 735 | |||||||||
| 736 | // Index into the lock array based on the current object address. | ||||||||
| 737 | static_assert(is_power_of_2(NINFLATIONLOCKS), "must be"); | ||||||||
| 738 | int ix = (cast_from_oop<intptr_t>(obj) >> 5) & (NINFLATIONLOCKS-1); | ||||||||
| 739 | int YieldThenBlock = 0; | ||||||||
| 740 |         assert(ix >= 0 && ix < NINFLATIONLOCKS, "invariant")do { if (!(ix >= 0 && ix < NINFLATIONLOCKS)) { ( *g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 740, "assert(" "ix >= 0 && ix < NINFLATIONLOCKS" ") failed", "invariant"); ::breakpoint(); } } while (0);  | ||||||||
| 741 | gInflationLocks[ix]->lock(); | ||||||||
| 742 | while (obj->mark_acquire() == markWord::INFLATING()) { | ||||||||
| 743 | // Beware: naked_yield() is advisory and has almost no effect on some platforms | ||||||||
| 744 | // so we periodically call current->_ParkEvent->park(1). | ||||||||
| 745 | // We use a mixed spin/yield/block mechanism. | ||||||||
| 746 | if ((YieldThenBlock++) >= 16) { | ||||||||
| 747 | Thread::current()->_ParkEvent->park(1); | ||||||||
| 748 | } else { | ||||||||
| 749 | os::naked_yield(); | ||||||||
| 750 | } | ||||||||
| 751 | } | ||||||||
| 752 | gInflationLocks[ix]->unlock(); | ||||||||
| 753 | } | ||||||||
| 754 | } else { | ||||||||
| 755 | SpinPause(); // SMP-polite spinning | ||||||||
| 756 | } | ||||||||
| 757 | } | ||||||||
| 758 | } | ||||||||
| 759 | |||||||||
| 760 | // hashCode() generation : | ||||||||
| 761 | // | ||||||||
| 762 | // Possibilities: | ||||||||
| 763 | // * MD5Digest of {obj,stw_random} | ||||||||
| 764 | // * CRC32 of {obj,stw_random} or any linear-feedback shift register function. | ||||||||
| 765 | // * A DES- or AES-style SBox[] mechanism | ||||||||
| 766 | // * One of the Phi-based schemes, such as: | ||||||||
| 767 | // 2654435761 = 2^32 * Phi (golden ratio) | ||||||||
| 768 | // HashCodeValue = ((uintptr_t(obj) >> 3) * 2654435761) ^ GVars.stw_random ; | ||||||||
| 769 | // * A variation of Marsaglia's shift-xor RNG scheme. | ||||||||
| 770 | // * (obj ^ stw_random) is appealing, but can result | ||||||||
| 771 | // in undesirable regularity in the hashCode values of adjacent objects | ||||||||
| 772 | // (objects allocated back-to-back, in particular). This could potentially | ||||||||
| 773 | // result in hashtable collisions and reduced hashtable efficiency. | ||||||||
| 774 | // There are simple ways to "diffuse" the middle address bits over the | ||||||||
| 775 | // generated hashCode values: | ||||||||
| 776 | |||||||||
| 777 | static inline intptr_t get_next_hash(Thread* current, oop obj) { | ||||||||
| 778 | intptr_t value = 0; | ||||||||
| 779 | if (hashCode == 0) { | ||||||||
| 780 | // This form uses global Park-Miller RNG. | ||||||||
| 781 | // On MP system we'll have lots of RW access to a global, so the | ||||||||
| 782 | // mechanism induces lots of coherency traffic. | ||||||||
| 783 | value = os::random(); | ||||||||
| 784 | } else if (hashCode == 1) { | ||||||||
| 785 | // This variation has the property of being stable (idempotent) | ||||||||
| 786 | // between STW operations. This can be useful in some of the 1-0 | ||||||||
| 787 | // synchronization schemes. | ||||||||
| 788 | intptr_t addr_bits = cast_from_oop<intptr_t>(obj) >> 3; | ||||||||
| 789 | value = addr_bits ^ (addr_bits >> 5) ^ GVars.stw_random; | ||||||||
| 790 | } else if (hashCode == 2) { | ||||||||
| 791 | value = 1; // for sensitivity testing | ||||||||
| 792 | } else if (hashCode == 3) { | ||||||||
| 793 | value = ++GVars.hc_sequence; | ||||||||
| 794 | } else if (hashCode == 4) { | ||||||||
| 795 | value = cast_from_oop<intptr_t>(obj); | ||||||||
| 796 | } else { | ||||||||
| 797 | // Marsaglia's xor-shift scheme with thread-specific state | ||||||||
| 798 | // This is probably the best overall implementation -- we'll | ||||||||
| 799 | // likely make this the default in future releases. | ||||||||
| 800 | unsigned t = current->_hashStateX; | ||||||||
| 801 | t ^= (t << 11); | ||||||||
| 802 | current->_hashStateX = current->_hashStateY; | ||||||||
| 803 | current->_hashStateY = current->_hashStateZ; | ||||||||
| 804 | current->_hashStateZ = current->_hashStateW; | ||||||||
| 805 | unsigned v = current->_hashStateW; | ||||||||
| 806 | v = (v ^ (v >> 19)) ^ (t ^ (t >> 8)); | ||||||||
| 807 | current->_hashStateW = v; | ||||||||
| 808 | value = v; | ||||||||
| 809 | } | ||||||||
| 810 | |||||||||
| 811 | value &= markWord::hash_mask; | ||||||||
| 812 | if (value == 0) value = 0xBAD; | ||||||||
| 813 |   assert(value != markWord::no_hash, "invariant")do { if (!(value != markWord::no_hash)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 813, "assert(" "value != markWord::no_hash" ") failed", "invariant" ); ::breakpoint(); } } while (0);  | ||||||||
| 814 | return value; | ||||||||
| 815 | } | ||||||||
| 816 | |||||||||
| 817 | intptr_t ObjectSynchronizer::FastHashCode(Thread* current, oop obj) { | ||||||||
| 818 | |||||||||
| 819 | while (true) { | ||||||||
| 820 | ObjectMonitor* monitor = NULL__null; | ||||||||
| 821 | markWord temp, test; | ||||||||
| 822 | intptr_t hash; | ||||||||
| 823 | markWord mark = read_stable_mark(obj); | ||||||||
| 824 | if (VerifyHeavyMonitors) { | ||||||||
| 825 |       assert(UseHeavyMonitors, "+VerifyHeavyMonitors requires +UseHeavyMonitors")do { if (!(UseHeavyMonitors)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 825, "assert(" "UseHeavyMonitors" ") failed", "+VerifyHeavyMonitors requires +UseHeavyMonitors" ); ::breakpoint(); } } while (0);  | ||||||||
| 826 |       guarantee(!mark.has_locker(), "must not be stack locked")do { if (!(!mark.has_locker())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 826, "guarantee(" "!mark.has_locker()" ") failed", "must not be stack locked" ); ::breakpoint(); } } while (0);  | ||||||||
| 827 | } | ||||||||
| 828 | if (mark.is_neutral()) { // if this is a normal header | ||||||||
| 829 | hash = mark.hash(); | ||||||||
| 830 | if (hash != 0) { // if it has a hash, just return it | ||||||||
| 831 | return hash; | ||||||||
| 832 | } | ||||||||
| 833 | hash = get_next_hash(current, obj); // get a new hash | ||||||||
| 834 | temp = mark.copy_set_hash(hash); // merge the hash into header | ||||||||
| 835 | // try to install the hash | ||||||||
| 836 | test = obj->cas_set_mark(temp, mark); | ||||||||
| 837 | if (test == mark) { // if the hash was installed, return it | ||||||||
| 838 | return hash; | ||||||||
| 839 | } | ||||||||
| 840 | // Failed to install the hash. It could be that another thread | ||||||||
| 841 | // installed the hash just before our attempt or inflation has | ||||||||
| 842 | // occurred or... so we fall thru to inflate the monitor for | ||||||||
| 843 | // stability and then install the hash. | ||||||||
| 844 | } else if (mark.has_monitor()) { | ||||||||
| 845 | monitor = mark.monitor(); | ||||||||
| 846 | temp = monitor->header(); | ||||||||
| 847 |       assert(temp.is_neutral(), "invariant: header=" INTPTR_FORMAT, temp.value())do { if (!(temp.is_neutral())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 847, "assert(" "temp.is_neutral()" ") failed", "invariant: header=" "0x%016" "l" "x", temp.value()); ::breakpoint(); } } while ( 0);  | ||||||||
| 848 | hash = temp.hash(); | ||||||||
| 849 | if (hash != 0) { | ||||||||
| 850 | // It has a hash. | ||||||||
| 851 | |||||||||
| 852 | // Separate load of dmw/header above from the loads in | ||||||||
| 853 | // is_being_async_deflated(). | ||||||||
| 854 | |||||||||
| 855 | // dmw/header and _contentions may get written by different threads. | ||||||||
| 856 | // Make sure to observe them in the same order when having several observers. | ||||||||
| 857 | OrderAccess::loadload_for_IRIW(); | ||||||||
| 858 | |||||||||
| 859 | if (monitor->is_being_async_deflated()) { | ||||||||
| 860 | // But we can't safely use the hash if we detect that async | ||||||||
| 861 | // deflation has occurred. So we attempt to restore the | ||||||||
| 862 | // header/dmw to the object's header so that we only retry | ||||||||
| 863 | // once if the deflater thread happens to be slow. | ||||||||
| 864 | monitor->install_displaced_markword_in_object(obj); | ||||||||
| 865 | continue; | ||||||||
| 866 | } | ||||||||
| 867 | return hash; | ||||||||
| 868 | } | ||||||||
| 869 | // Fall thru so we only have one place that installs the hash in | ||||||||
| 870 | // the ObjectMonitor. | ||||||||
| 871 | } else if (current->is_lock_owned((address)mark.locker())) { | ||||||||
| 872 | // This is a stack lock owned by the calling thread so fetch the | ||||||||
| 873 | // displaced markWord from the BasicLock on the stack. | ||||||||
| 874 | temp = mark.displaced_mark_helper(); | ||||||||
| 875 |       assert(temp.is_neutral(), "invariant: header=" INTPTR_FORMAT, temp.value())do { if (!(temp.is_neutral())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 875, "assert(" "temp.is_neutral()" ") failed", "invariant: header=" "0x%016" "l" "x", temp.value()); ::breakpoint(); } } while ( 0);  | ||||||||
| 876 | hash = temp.hash(); | ||||||||
| 877 | if (hash != 0) { // if it has a hash, just return it | ||||||||
| 878 | return hash; | ||||||||
| 879 | } | ||||||||
| 880 | // WARNING: | ||||||||
| 881 | // The displaced header in the BasicLock on a thread's stack | ||||||||
| 882 | // is strictly immutable. It CANNOT be changed in ANY cases. | ||||||||
| 883 | // So we have to inflate the stack lock into an ObjectMonitor | ||||||||
| 884 | // even if the current thread owns the lock. The BasicLock on | ||||||||
| 885 | // a thread's stack can be asynchronously read by other threads | ||||||||
| 886 | // during an inflate() call so any change to that stack memory | ||||||||
| 887 | // may not propagate to other threads correctly. | ||||||||
| 888 | } | ||||||||
| 889 | |||||||||
| 890 | // Inflate the monitor to set the hash. | ||||||||
| 891 | |||||||||
| 892 | // An async deflation can race after the inflate() call and before we | ||||||||
| 893 | // can update the ObjectMonitor's header with the hash value below. | ||||||||
| 894 | monitor = inflate(current, obj, inflate_cause_hash_code); | ||||||||
| 895 | // Load ObjectMonitor's header/dmw field and see if it has a hash. | ||||||||
| 896 | mark = monitor->header(); | ||||||||
| 897 |     assert(mark.is_neutral(), "invariant: header=" INTPTR_FORMAT, mark.value())do { if (!(mark.is_neutral())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 897, "assert(" "mark.is_neutral()" ") failed", "invariant: header=" "0x%016" "l" "x", mark.value()); ::breakpoint(); } } while ( 0);  | ||||||||
| 898 | hash = mark.hash(); | ||||||||
| 899 | if (hash == 0) { // if it does not have a hash | ||||||||
| 900 | hash = get_next_hash(current, obj); // get a new hash | ||||||||
| 901 | temp = mark.copy_set_hash(hash) ; // merge the hash into header | ||||||||
| 902 |       assert(temp.is_neutral(), "invariant: header=" INTPTR_FORMAT, temp.value())do { if (!(temp.is_neutral())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 902, "assert(" "temp.is_neutral()" ") failed", "invariant: header=" "0x%016" "l" "x", temp.value()); ::breakpoint(); } } while ( 0);  | ||||||||
| 903 | uintptr_t v = Atomic::cmpxchg((volatile uintptr_t*)monitor->header_addr(), mark.value(), temp.value()); | ||||||||
| 904 | test = markWord(v); | ||||||||
| 905 | if (test != mark) { | ||||||||
| 906 | // The attempt to update the ObjectMonitor's header/dmw field | ||||||||
| 907 | // did not work. This can happen if another thread managed to | ||||||||
| 908 | // merge in the hash just before our cmpxchg(). | ||||||||
| 909 | // If we add any new usages of the header/dmw field, this code | ||||||||
| 910 | // will need to be updated. | ||||||||
| 911 | hash = test.hash(); | ||||||||
| 912 |         assert(test.is_neutral(), "invariant: header=" INTPTR_FORMAT, test.value())do { if (!(test.is_neutral())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 912, "assert(" "test.is_neutral()" ") failed", "invariant: header=" "0x%016" "l" "x", test.value()); ::breakpoint(); } } while ( 0);  | ||||||||
| 913 |         assert(hash != 0, "should only have lost the race to a thread that set a non-zero hash")do { if (!(hash != 0)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 913, "assert(" "hash != 0" ") failed", "should only have lost the race to a thread that set a non-zero hash" ); ::breakpoint(); } } while (0);  | ||||||||
| 914 | } | ||||||||
| 915 | if (monitor->is_being_async_deflated()) { | ||||||||
| 916 | // If we detect that async deflation has occurred, then we | ||||||||
| 917 | // attempt to restore the header/dmw to the object's header | ||||||||
| 918 | // so that we only retry once if the deflater thread happens | ||||||||
| 919 | // to be slow. | ||||||||
| 920 | monitor->install_displaced_markword_in_object(obj); | ||||||||
| 921 | continue; | ||||||||
| 922 | } | ||||||||
| 923 | } | ||||||||
| 924 | // We finally get the hash. | ||||||||
| 925 | return hash; | ||||||||
| 926 | } | ||||||||
| 927 | } | ||||||||
| 928 | |||||||||
| 929 | // Deprecated -- use FastHashCode() instead. | ||||||||
| 930 | |||||||||
| 931 | intptr_t ObjectSynchronizer::identity_hash_value_for(Handle obj) { | ||||||||
| 932 | return FastHashCode(Thread::current(), obj()); | ||||||||
| 933 | } | ||||||||
| 934 | |||||||||
| 935 | |||||||||
| 936 | bool ObjectSynchronizer::current_thread_holds_lock(JavaThread* current, | ||||||||
| 937 | Handle h_obj) { | ||||||||
| 938 |   assert(current == JavaThread::current(), "Can only be called on current thread")do { if (!(current == JavaThread::current())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 938, "assert(" "current == JavaThread::current()" ") failed" , "Can only be called on current thread"); ::breakpoint(); } } while (0);  | ||||||||
| 939 | oop obj = h_obj(); | ||||||||
| 940 | |||||||||
| 941 | markWord mark = read_stable_mark(obj); | ||||||||
| 942 | |||||||||
| 943 | // Uncontended case, header points to stack | ||||||||
| 944 | if (mark.has_locker()) { | ||||||||
| 945 | return current->is_lock_owned((address)mark.locker()); | ||||||||
| 946 | } | ||||||||
| 947 | // Contended case, header points to ObjectMonitor (tagged pointer) | ||||||||
| 948 | if (mark.has_monitor()) { | ||||||||
| 949 | // The first stage of async deflation does not affect any field | ||||||||
| 950 | // used by this comparison so the ObjectMonitor* is usable here. | ||||||||
| 951 | ObjectMonitor* monitor = mark.monitor(); | ||||||||
| 952 | return monitor->is_entered(current) != 0; | ||||||||
| 953 | } | ||||||||
| 954 | // Unlocked case, header in place | ||||||||
| 955 |   assert(mark.is_neutral(), "sanity check")do { if (!(mark.is_neutral())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 955, "assert(" "mark.is_neutral()" ") failed", "sanity check" ); ::breakpoint(); } } while (0);  | ||||||||
| 956 | return false; | ||||||||
| 957 | } | ||||||||
| 958 | |||||||||
| 959 | // FIXME: jvmti should call this | ||||||||
| 960 | JavaThread* ObjectSynchronizer::get_lock_owner(ThreadsList * t_list, Handle h_obj) { | ||||||||
| 961 | oop obj = h_obj(); | ||||||||
| 962 | address owner = NULL__null; | ||||||||
| 963 | |||||||||
| 964 | markWord mark = read_stable_mark(obj); | ||||||||
| 965 | |||||||||
| 966 | // Uncontended case, header points to stack | ||||||||
| 967 | if (mark.has_locker()) { | ||||||||
| 968 | owner = (address) mark.locker(); | ||||||||
| 969 | } | ||||||||
| 970 | |||||||||
| 971 | // Contended case, header points to ObjectMonitor (tagged pointer) | ||||||||
| 972 | else if (mark.has_monitor()) { | ||||||||
| 973 | // The first stage of async deflation does not affect any field | ||||||||
| 974 | // used by this comparison so the ObjectMonitor* is usable here. | ||||||||
| 975 | ObjectMonitor* monitor = mark.monitor(); | ||||||||
| 976 |     assert(monitor != NULL, "monitor should be non-null")do { if (!(monitor != __null)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 976, "assert(" "monitor != __null" ") failed", "monitor should be non-null" ); ::breakpoint(); } } while (0);  | ||||||||
| 977 | owner = (address) monitor->owner(); | ||||||||
| 978 | } | ||||||||
| 979 | |||||||||
| 980 | if (owner != NULL__null) { | ||||||||
| 981 | // owning_thread_from_monitor_owner() may also return NULL here | ||||||||
| 982 | return Threads::owning_thread_from_monitor_owner(t_list, owner); | ||||||||
| 983 | } | ||||||||
| 984 | |||||||||
| 985 | // Unlocked case, header in place | ||||||||
| 986 | // Cannot have assertion since this object may have been | ||||||||
| 987 | // locked by another thread when reaching here. | ||||||||
| 988 | // assert(mark.is_neutral(), "sanity check"); | ||||||||
| 989 | |||||||||
| 990 | return NULL__null; | ||||||||
| 991 | } | ||||||||
| 992 | |||||||||
| 993 | // Visitors ... | ||||||||
| 994 | |||||||||
| 995 | void ObjectSynchronizer::monitors_iterate(MonitorClosure* closure, JavaThread* thread) { | ||||||||
| 996 | MonitorList::Iterator iter = _in_use_list.iterator(); | ||||||||
| 997 | while (iter.has_next()) { | ||||||||
| 998 | ObjectMonitor* mid = iter.next(); | ||||||||
| 999 | if (mid->owner() != thread) { | ||||||||
| 1000 | continue; | ||||||||
| 1001 | } | ||||||||
| 1002 | if (!mid->is_being_async_deflated() && mid->object_peek() != NULL__null) { | ||||||||
| 1003 | // Only process with closure if the object is set. | ||||||||
| 1004 | |||||||||
| 1005 | // monitors_iterate() is only called at a safepoint or when the | ||||||||
| 1006 | // target thread is suspended or when the target thread is | ||||||||
| 1007 | // operating on itself. The current closures in use today are | ||||||||
| 1008 | // only interested in an owned ObjectMonitor and ownership | ||||||||
| 1009 | // cannot be dropped under the calling contexts so the | ||||||||
| 1010 | // ObjectMonitor cannot be async deflated. | ||||||||
| 1011 | closure->do_monitor(mid); | ||||||||
| 1012 | } | ||||||||
| 1013 | } | ||||||||
| 1014 | } | ||||||||
| 1015 | |||||||||
| 1016 | static bool monitors_used_above_threshold(MonitorList* list) { | ||||||||
| 1017 | if (MonitorUsedDeflationThreshold == 0) { // disabled case is easy | ||||||||
| 1018 | return false; | ||||||||
| 1019 | } | ||||||||
| 1020 | // Start with ceiling based on a per-thread estimate: | ||||||||
| 1021 | size_t ceiling = ObjectSynchronizer::in_use_list_ceiling(); | ||||||||
| 1022 | size_t old_ceiling = ceiling; | ||||||||
| 1023 | if (ceiling < list->max()) { | ||||||||
| 1024 | // The max used by the system has exceeded the ceiling so use that: | ||||||||
| 1025 | ceiling = list->max(); | ||||||||
| 1026 | } | ||||||||
| 1027 | size_t monitors_used = list->count(); | ||||||||
| 1028 | if (monitors_used == 0) { // empty list is easy | ||||||||
| 1029 | return false; | ||||||||
| 1030 | } | ||||||||
| 1031 | if (NoAsyncDeflationProgressMax != 0 && | ||||||||
| 1032 | _no_progress_cnt >= NoAsyncDeflationProgressMax) { | ||||||||
| 1033 | float remainder = (100.0 - MonitorUsedDeflationThreshold) / 100.0; | ||||||||
| 1034 | size_t new_ceiling = ceiling + (ceiling * remainder) + 1; | ||||||||
| 1035 | ObjectSynchronizer::set_in_use_list_ceiling(new_ceiling); | ||||||||
| 1036 |     log_info(monitorinflation)(!(LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG) , (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::is_level(LogLevel::Info))) ? (void)0 : LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG) , (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel::Info>("Too many deflations without progress; "  | ||||||||
| 1037 | "bumping in_use_list_ceiling from " SIZE_FORMAT"%" "l" "u" | ||||||||
| 1038 | " to " SIZE_FORMAT"%" "l" "u", old_ceiling, new_ceiling); | ||||||||
| 1039 | _no_progress_cnt = 0; | ||||||||
| 1040 | ceiling = new_ceiling; | ||||||||
| 1041 | } | ||||||||
| 1042 | |||||||||
| 1043 | // Check if our monitor usage is above the threshold: | ||||||||
| 1044 | size_t monitor_usage = (monitors_used * 100LL) / ceiling; | ||||||||
| 1045 | return int(monitor_usage) > MonitorUsedDeflationThreshold; | ||||||||
| 1046 | } | ||||||||
| 1047 | |||||||||
| 1048 | size_t ObjectSynchronizer::in_use_list_ceiling() { | ||||||||
| 1049 | return _in_use_list_ceiling; | ||||||||
| 1050 | } | ||||||||
| 1051 | |||||||||
| 1052 | void ObjectSynchronizer::dec_in_use_list_ceiling() { | ||||||||
| 1053 | Atomic::sub(&_in_use_list_ceiling, AvgMonitorsPerThreadEstimate); | ||||||||
| 1054 | } | ||||||||
| 1055 | |||||||||
| 1056 | void ObjectSynchronizer::inc_in_use_list_ceiling() { | ||||||||
| 1057 | Atomic::add(&_in_use_list_ceiling, AvgMonitorsPerThreadEstimate); | ||||||||
| 1058 | } | ||||||||
| 1059 | |||||||||
| 1060 | void ObjectSynchronizer::set_in_use_list_ceiling(size_t new_value) { | ||||||||
| 1061 | _in_use_list_ceiling = new_value; | ||||||||
| 1062 | } | ||||||||
| 1063 | |||||||||
| 1064 | bool ObjectSynchronizer::is_async_deflation_needed() { | ||||||||
| 1065 | if (is_async_deflation_requested()) { | ||||||||
| 1066 | // Async deflation request. | ||||||||
| 1067 | return true; | ||||||||
| 1068 | } | ||||||||
| 1069 | if (AsyncDeflationInterval > 0 && | ||||||||
| 1070 | time_since_last_async_deflation_ms() > AsyncDeflationInterval && | ||||||||
| 1071 | monitors_used_above_threshold(&_in_use_list)) { | ||||||||
| 1072 | // It's been longer than our specified deflate interval and there | ||||||||
| 1073 | // are too many monitors in use. We don't deflate more frequently | ||||||||
| 1074 | // than AsyncDeflationInterval (unless is_async_deflation_requested) | ||||||||
| 1075 | // in order to not swamp the MonitorDeflationThread. | ||||||||
| 1076 | return true; | ||||||||
| 1077 | } | ||||||||
| 1078 | return false; | ||||||||
| 1079 | } | ||||||||
| 1080 | |||||||||
| 1081 | bool ObjectSynchronizer::request_deflate_idle_monitors() { | ||||||||
| 1082 | JavaThread* current = JavaThread::current(); | ||||||||
| 1083 | bool ret_code = false; | ||||||||
| 1084 | |||||||||
| 1085 | jlong last_time = last_async_deflation_time_ns(); | ||||||||
| 1086 | set_is_async_deflation_requested(true); | ||||||||
| 1087 | { | ||||||||
| 1088 | MonitorLocker ml(MonitorDeflation_lock, Mutex::_no_safepoint_check_flag); | ||||||||
| 1089 | ml.notify_all(); | ||||||||
| 1090 | } | ||||||||
| 1091 | const int N_CHECKS = 5; | ||||||||
| 1092 | for (int i = 0; i < N_CHECKS; i++) { // sleep for at most 5 seconds | ||||||||
| 1093 | if (last_async_deflation_time_ns() > last_time) { | ||||||||
| 1094 |       log_info(monitorinflation)(!(LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG) , (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::is_level(LogLevel::Info))) ? (void)0 : LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG) , (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel::Info>("Async Deflation happened after %d check(s).", i);  | ||||||||
| 1095 | ret_code = true; | ||||||||
| 1096 | break; | ||||||||
| 1097 | } | ||||||||
| 1098 | { | ||||||||
| 1099 | // JavaThread has to honor the blocking protocol. | ||||||||
| 1100 | ThreadBlockInVM tbivm(current); | ||||||||
| 1101 | os::naked_short_sleep(999); // sleep for almost 1 second | ||||||||
| 1102 | } | ||||||||
| 1103 | } | ||||||||
| 1104 | if (!ret_code) { | ||||||||
| 1105 |     log_info(monitorinflation)(!(LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG) , (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::is_level(LogLevel::Info))) ? (void)0 : LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG) , (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel::Info>("Async Deflation DID NOT happen after %d checks.", N_CHECKS);  | ||||||||
| 1106 | } | ||||||||
| 1107 | |||||||||
| 1108 | return ret_code; | ||||||||
| 1109 | } | ||||||||
| 1110 | |||||||||
| 1111 | jlong ObjectSynchronizer::time_since_last_async_deflation_ms() { | ||||||||
| 1112 | return (os::javaTimeNanos() - last_async_deflation_time_ns()) / (NANOUNITS / MILLIUNITS); | ||||||||
| 1113 | } | ||||||||
| 1114 | |||||||||
| 1115 | static void post_monitor_inflate_event(EventJavaMonitorInflate* event, | ||||||||
| 1116 | const oop obj, | ||||||||
| 1117 | ObjectSynchronizer::InflateCause cause) { | ||||||||
| 1118 |   assert(event != NULL, "invariant")do { if (!(event != __null)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 1118, "assert(" "event != __null" ") failed", "invariant"); ::breakpoint(); } } while (0);  | ||||||||
| 1119 |   assert(event->should_commit(), "invariant")do { if (!(event->should_commit())) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 1119, "assert(" "event->should_commit()" ") failed", "invariant" ); ::breakpoint(); } } while (0);  | ||||||||
| 1120 | event->set_monitorClass(obj->klass()); | ||||||||
| 1121 | event->set_address((uintptr_t)(void*)obj); | ||||||||
| 1122 | event->set_cause((u1)cause); | ||||||||
| 1123 | event->commit(); | ||||||||
| 1124 | } | ||||||||
| 1125 | |||||||||
| 1126 | // Fast path code shared by multiple functions | ||||||||
| 1127 | void ObjectSynchronizer::inflate_helper(oop obj) { | ||||||||
| 1128 | markWord mark = obj->mark_acquire(); | ||||||||
| 1129 | if (mark.has_monitor()) { | ||||||||
| 1130 | ObjectMonitor* monitor = mark.monitor(); | ||||||||
| 1131 | markWord dmw = monitor->header(); | ||||||||
| 1132 |     assert(dmw.is_neutral(), "sanity check: header=" INTPTR_FORMAT, dmw.value())do { if (!(dmw.is_neutral())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 1132, "assert(" "dmw.is_neutral()" ") failed", "sanity check: header=" "0x%016" "l" "x", dmw.value()); ::breakpoint(); } } while (0 );  | ||||||||
| 1133 | return; | ||||||||
| 1134 | } | ||||||||
| 1135 | (void)inflate(Thread::current(), obj, inflate_cause_vm_internal); | ||||||||
| 1136 | } | ||||||||
| 1137 | |||||||||
| 1138 | ObjectMonitor* ObjectSynchronizer::inflate(Thread* current, oop object, | ||||||||
| 1139 | const InflateCause cause) { | ||||||||
| 1140 | EventJavaMonitorInflate event; | ||||||||
| 1141 | |||||||||
| 1142 | for (;;) { | ||||||||
| 1143 | const markWord mark = object->mark_acquire(); | ||||||||
| 1144 | |||||||||
| 1145 | // The mark can be in one of the following states: | ||||||||
| 1146 | // * Inflated - just return | ||||||||
| 1147 | // * Stack-locked - coerce it to inflated | ||||||||
| 1148 | // * INFLATING - busy wait for conversion to complete | ||||||||
| 1149 | // * Neutral - aggressively inflate the object. | ||||||||
| 1150 | |||||||||
| 1151 | // CASE: inflated | ||||||||
| 1152 | if (mark.has_monitor()) { | ||||||||
| 1153 | ObjectMonitor* inf = mark.monitor(); | ||||||||
| 1154 | markWord dmw = inf->header(); | ||||||||
| 1155 |       assert(dmw.is_neutral(), "invariant: header=" INTPTR_FORMAT, dmw.value())do { if (!(dmw.is_neutral())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 1155, "assert(" "dmw.is_neutral()" ") failed", "invariant: header=" "0x%016" "l" "x", dmw.value()); ::breakpoint(); } } while (0 );  | ||||||||
| 1156 | return inf; | ||||||||
| 1157 | } | ||||||||
| 1158 | |||||||||
| 1159 | // CASE: inflation in progress - inflating over a stack-lock. | ||||||||
| 1160 | // Some other thread is converting from stack-locked to inflated. | ||||||||
| 1161 | // Only that thread can complete inflation -- other threads must wait. | ||||||||
| 1162 | // The INFLATING value is transient. | ||||||||
| 1163 | // Currently, we spin/yield/park and poll the markword, waiting for inflation to finish. | ||||||||
| 1164 | // We could always eliminate polling by parking the thread on some auxiliary list. | ||||||||
| 1165 | if (mark == markWord::INFLATING()) { | ||||||||
| 1166 | read_stable_mark(object); | ||||||||
| 1167 | continue; | ||||||||
| 1168 | } | ||||||||
| 1169 | |||||||||
| 1170 | // CASE: stack-locked | ||||||||
| 1171 | // Could be stack-locked either by this thread or by some other thread. | ||||||||
| 1172 | // | ||||||||
| 1173 | // Note that we allocate the ObjectMonitor speculatively, _before_ attempting | ||||||||
| 1174 | // to install INFLATING into the mark word. We originally installed INFLATING, | ||||||||
| 1175 | // allocated the ObjectMonitor, and then finally STed the address of the | ||||||||
| 1176 | // ObjectMonitor into the mark. This was correct, but artificially lengthened | ||||||||
| 1177 | // the interval in which INFLATING appeared in the mark, thus increasing | ||||||||
| 1178 | // the odds of inflation contention. | ||||||||
| 1179 | |||||||||
| 1180 |     LogStreamHandle(Trace, monitorinflation)LogStreamTemplate<LogLevel::Trace, (LogTag::_monitorinflation ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) , (LogTag::__NO_TAG), (LogTag::__NO_TAG)> lsh;  | ||||||||
| 1181 | |||||||||
| 1182 | if (mark.has_locker()) { | ||||||||
| 1183 | ObjectMonitor* m = new ObjectMonitor(object); | ||||||||
| 1184 | // Optimistically prepare the ObjectMonitor - anticipate successful CAS | ||||||||
| 1185 | // We do this before the CAS in order to minimize the length of time | ||||||||
| 1186 | // in which INFLATING appears in the mark. | ||||||||
| 1187 | |||||||||
| 1188 | markWord cmp = object->cas_set_mark(markWord::INFLATING(), mark); | ||||||||
| 1189 | if (cmp != mark) { | ||||||||
| 1190 | delete m; | ||||||||
| 1191 | continue; // Interference -- just retry | ||||||||
| 1192 | } | ||||||||
| 1193 | |||||||||
| 1194 | // We've successfully installed INFLATING (0) into the mark-word. | ||||||||
| 1195 | // This is the only case where 0 will appear in a mark-word. | ||||||||
| 1196 | // Only the singular thread that successfully swings the mark-word | ||||||||
| 1197 | // to 0 can perform (or more precisely, complete) inflation. | ||||||||
| 1198 | // | ||||||||
| 1199 | // Why do we CAS a 0 into the mark-word instead of just CASing the | ||||||||
| 1200 | // mark-word from the stack-locked value directly to the new inflated state? | ||||||||
| 1201 | // Consider what happens when a thread unlocks a stack-locked object. | ||||||||
| 1202 | // It attempts to use CAS to swing the displaced header value from the | ||||||||
| 1203 | // on-stack BasicLock back into the object header. Recall also that the | ||||||||
| 1204 | // header value (hash code, etc) can reside in (a) the object header, or | ||||||||
| 1205 | // (b) a displaced header associated with the stack-lock, or (c) a displaced | ||||||||
| 1206 | // header in an ObjectMonitor. The inflate() routine must copy the header | ||||||||
| 1207 | // value from the BasicLock on the owner's stack to the ObjectMonitor, all | ||||||||
| 1208 | // the while preserving the hashCode stability invariants. If the owner | ||||||||
| 1209 | // decides to release the lock while the value is 0, the unlock will fail | ||||||||
| 1210 | // and control will eventually pass from slow_exit() to inflate. The owner | ||||||||
| 1211 | // will then spin, waiting for the 0 value to disappear. Put another way, | ||||||||
| 1212 | // the 0 causes the owner to stall if the owner happens to try to | ||||||||
| 1213 | // drop the lock (restoring the header from the BasicLock to the object) | ||||||||
| 1214 | // while inflation is in-progress. This protocol avoids races that might | ||||||||
| 1215 | // would otherwise permit hashCode values to change or "flicker" for an object. | ||||||||
| 1216 | // Critically, while object->mark is 0 mark.displaced_mark_helper() is stable. | ||||||||
| 1217 | // 0 serves as a "BUSY" inflate-in-progress indicator. | ||||||||
| 1218 | |||||||||
| 1219 | |||||||||
| 1220 | // fetch the displaced mark from the owner's stack. | ||||||||
| 1221 | // The owner can't die or unwind past the lock while our INFLATING | ||||||||
| 1222 | // object is in the mark. Furthermore the owner can't complete | ||||||||
| 1223 | // an unlock on the object, either. | ||||||||
| 1224 | markWord dmw = mark.displaced_mark_helper(); | ||||||||
| 1225 | // Catch if the object's header is not neutral (not locked and | ||||||||
| 1226 | // not marked is what we care about here). | ||||||||
| 1227 |       assert(dmw.is_neutral(), "invariant: header=" INTPTR_FORMAT, dmw.value())do { if (!(dmw.is_neutral())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 1227, "assert(" "dmw.is_neutral()" ") failed", "invariant: header=" "0x%016" "l" "x", dmw.value()); ::breakpoint(); } } while (0 );  | ||||||||
| 1228 | |||||||||
| 1229 | // Setup monitor fields to proper values -- prepare the monitor | ||||||||
| 1230 | m->set_header(dmw); | ||||||||
| 1231 | |||||||||
| 1232 | // Optimization: if the mark.locker stack address is associated | ||||||||
| 1233 | // with this thread we could simply set m->_owner = current. | ||||||||
| 1234 | // Note that a thread can inflate an object | ||||||||
| 1235 | // that it has stack-locked -- as might happen in wait() -- directly | ||||||||
| 1236 | // with CAS. That is, we can avoid the xchg-NULL .... ST idiom. | ||||||||
| 1237 | m->set_owner_from(NULL__null, mark.locker()); | ||||||||
| 1238 | // TODO-FIXME: assert BasicLock->dhw != 0. | ||||||||
| 1239 | |||||||||
| 1240 | // Must preserve store ordering. The monitor state must | ||||||||
| 1241 | // be stable at the time of publishing the monitor address. | ||||||||
| 1242 |       guarantee(object->mark() == markWord::INFLATING(), "invariant")do { if (!(object->mark() == markWord::INFLATING())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 1242, "guarantee(" "object->mark() == markWord::INFLATING()" ") failed", "invariant"); ::breakpoint(); } } while (0);  | ||||||||
| 1243 | // Release semantics so that above set_object() is seen first. | ||||||||
| 1244 | object->release_set_mark(markWord::encode(m)); | ||||||||
| 1245 | |||||||||
| 1246 | // Once ObjectMonitor is configured and the object is associated | ||||||||
| 1247 | // with the ObjectMonitor, it is safe to allow async deflation: | ||||||||
| 1248 | _in_use_list.add(m); | ||||||||
| 1249 | |||||||||
| 1250 | // Hopefully the performance counters are allocated on distinct cache lines | ||||||||
| 1251 | // to avoid false sharing on MP systems ... | ||||||||
| 1252 |       OM_PERFDATA_OP(Inflations, inc())do { if (ObjectMonitor::_sync_Inflations != __null && PerfDataManager::has_PerfData()) { ObjectMonitor::_sync_Inflations ->inc(); } } while (0);  | ||||||||
| 1253 |       if (log_is_enabled(Trace, monitorinflation)(LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG), ( LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag ::__NO_TAG)>::is_level(LogLevel::Trace))) {  | ||||||||
| 1254 | ResourceMark rm(current); | ||||||||
| 1255 | lsh.print_cr("inflate(has_locker): object=" INTPTR_FORMAT"0x%016" "l" "x" ", mark=" | ||||||||
| 1256 | INTPTR_FORMAT"0x%016" "l" "x" ", type='%s'", p2i(object), | ||||||||
| 1257 | object->mark().value(), object->klass()->external_name()); | ||||||||
| 1258 | } | ||||||||
| 1259 | if (event.should_commit()) { | ||||||||
| 1260 | post_monitor_inflate_event(&event, object, cause); | ||||||||
| 1261 | } | ||||||||
| 1262 | return m; | ||||||||
| 1263 | } | ||||||||
| 1264 | |||||||||
| 1265 | // CASE: neutral | ||||||||
| 1266 | // TODO-FIXME: for entry we currently inflate and then try to CAS _owner. | ||||||||
| 1267 | // If we know we're inflating for entry it's better to inflate by swinging a | ||||||||
| 1268 | // pre-locked ObjectMonitor pointer into the object header. A successful | ||||||||
| 1269 | // CAS inflates the object *and* confers ownership to the inflating thread. | ||||||||
| 1270 | // In the current implementation we use a 2-step mechanism where we CAS() | ||||||||
| 1271 | // to inflate and then CAS() again to try to swing _owner from NULL to current. | ||||||||
| 1272 | // An inflateTry() method that we could call from enter() would be useful. | ||||||||
| 1273 | |||||||||
| 1274 | // Catch if the object's header is not neutral (not locked and | ||||||||
| 1275 | // not marked is what we care about here). | ||||||||
| 1276 |     assert(mark.is_neutral(), "invariant: header=" INTPTR_FORMAT, mark.value())do { if (!(mark.is_neutral())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 1276, "assert(" "mark.is_neutral()" ") failed", "invariant: header=" "0x%016" "l" "x", mark.value()); ::breakpoint(); } } while ( 0);  | ||||||||
| 1277 | ObjectMonitor* m = new ObjectMonitor(object); | ||||||||
| 1278 | // prepare m for installation - set monitor to initial state | ||||||||
| 1279 | m->set_header(mark); | ||||||||
| 1280 | |||||||||
| 1281 | if (object->cas_set_mark(markWord::encode(m), mark) != mark) { | ||||||||
| 1282 | delete m; | ||||||||
| 1283 | m = NULL__null; | ||||||||
| 1284 | continue; | ||||||||
| 1285 | // interference - the markword changed - just retry. | ||||||||
| 1286 | // The state-transitions are one-way, so there's no chance of | ||||||||
| 1287 | // live-lock -- "Inflated" is an absorbing state. | ||||||||
| 1288 | } | ||||||||
| 1289 | |||||||||
| 1290 | // Once the ObjectMonitor is configured and object is associated | ||||||||
| 1291 | // with the ObjectMonitor, it is safe to allow async deflation: | ||||||||
| 1292 | _in_use_list.add(m); | ||||||||
| 1293 | |||||||||
| 1294 | // Hopefully the performance counters are allocated on distinct | ||||||||
| 1295 | // cache lines to avoid false sharing on MP systems ... | ||||||||
| 1296 |     OM_PERFDATA_OP(Inflations, inc())do { if (ObjectMonitor::_sync_Inflations != __null && PerfDataManager::has_PerfData()) { ObjectMonitor::_sync_Inflations ->inc(); } } while (0);  | ||||||||
| 1297 |     if (log_is_enabled(Trace, monitorinflation)(LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG), ( LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag ::__NO_TAG)>::is_level(LogLevel::Trace))) {  | ||||||||
| 1298 | ResourceMark rm(current); | ||||||||
| 1299 | lsh.print_cr("inflate(neutral): object=" INTPTR_FORMAT"0x%016" "l" "x" ", mark=" | ||||||||
| 1300 | INTPTR_FORMAT"0x%016" "l" "x" ", type='%s'", p2i(object), | ||||||||
| 1301 | object->mark().value(), object->klass()->external_name()); | ||||||||
| 1302 | } | ||||||||
| 1303 | if (event.should_commit()) { | ||||||||
| 1304 | post_monitor_inflate_event(&event, object, cause); | ||||||||
| 1305 | } | ||||||||
| 1306 | return m; | ||||||||
| 1307 | } | ||||||||
| 1308 | } | ||||||||
| 1309 | |||||||||
| 1310 | void ObjectSynchronizer::chk_for_block_req(JavaThread* current, const char* op_name, | ||||||||
| 1311 | const char* cnt_name, size_t cnt, | ||||||||
| 1312 | LogStream* ls, elapsedTimer* timer_p) { | ||||||||
| 1313 | if (!SafepointMechanism::should_process(current)) { | ||||||||
| 1314 | return; | ||||||||
| 1315 | } | ||||||||
| 1316 | |||||||||
| 1317 | // A safepoint/handshake has started. | ||||||||
| 1318 | if (ls != NULL__null) { | ||||||||
| 1319 | timer_p->stop(); | ||||||||
| 1320 | ls->print_cr("pausing %s: %s=" SIZE_FORMAT"%" "l" "u" ", in_use_list stats: ceiling=" | ||||||||
| 1321 | SIZE_FORMAT"%" "l" "u" ", count=" SIZE_FORMAT"%" "l" "u" ", max=" SIZE_FORMAT"%" "l" "u", | ||||||||
| 1322 | op_name, cnt_name, cnt, in_use_list_ceiling(), | ||||||||
| 1323 | _in_use_list.count(), _in_use_list.max()); | ||||||||
| 1324 | } | ||||||||
| 1325 | |||||||||
| 1326 | { | ||||||||
| 1327 | // Honor block request. | ||||||||
| 1328 | ThreadBlockInVM tbivm(current); | ||||||||
| 1329 | } | ||||||||
| 1330 | |||||||||
| 1331 | if (ls != NULL__null) { | ||||||||
| 1332 | ls->print_cr("resuming %s: in_use_list stats: ceiling=" SIZE_FORMAT"%" "l" "u" | ||||||||
| 1333 | ", count=" SIZE_FORMAT"%" "l" "u" ", max=" SIZE_FORMAT"%" "l" "u", op_name, | ||||||||
| 1334 | in_use_list_ceiling(), _in_use_list.count(), _in_use_list.max()); | ||||||||
| 1335 | timer_p->start(); | ||||||||
| 1336 | } | ||||||||
| 1337 | } | ||||||||
| 1338 | |||||||||
| 1339 | // Walk the in-use list and deflate (at most MonitorDeflationMax) idle | ||||||||
| 1340 | // ObjectMonitors. Returns the number of deflated ObjectMonitors. | ||||||||
| 1341 | size_t ObjectSynchronizer::deflate_monitor_list(Thread* current, LogStream* ls, | ||||||||
| 1342 | elapsedTimer* timer_p) { | ||||||||
| 1343 | MonitorList::Iterator iter = _in_use_list.iterator(); | ||||||||
| 1344 | size_t deflated_count = 0; | ||||||||
| 1345 | |||||||||
| 1346 | while (iter.has_next()) { | ||||||||
| 1347 | if (deflated_count >= (size_t)MonitorDeflationMax) { | ||||||||
| 1348 | break; | ||||||||
| 1349 | } | ||||||||
| 1350 | ObjectMonitor* mid = iter.next(); | ||||||||
| 1351 | if (mid->deflate_monitor()) { | ||||||||
| 1352 | deflated_count++; | ||||||||
| 1353 | } | ||||||||
| 1354 | |||||||||
| 1355 | if (current->is_Java_thread()) { | ||||||||
| 1356 | // A JavaThread must check for a safepoint/handshake and honor it. | ||||||||
| 1357 | chk_for_block_req(JavaThread::cast(current), "deflation", "deflated_count", | ||||||||
| 1358 | deflated_count, ls, timer_p); | ||||||||
| 1359 | } | ||||||||
| 1360 | } | ||||||||
| 1361 | |||||||||
| 1362 | return deflated_count; | ||||||||
| 1363 | } | ||||||||
| 1364 | |||||||||
| 1365 | class HandshakeForDeflation : public HandshakeClosure { | ||||||||
| 1366 | public: | ||||||||
| 1367 | HandshakeForDeflation() : HandshakeClosure("HandshakeForDeflation") {} | ||||||||
| 1368 | |||||||||
| 1369 | void do_thread(Thread* thread) { | ||||||||
| 1370 |     log_trace(monitorinflation)(!(LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG) , (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::is_level(LogLevel::Trace))) ? (void) 0 : LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) , (LogTag::__NO_TAG)>::write<LogLevel::Trace>("HandshakeForDeflation::do_thread: thread="  | ||||||||
| 1371 | INTPTR_FORMAT"0x%016" "l" "x", p2i(thread)); | ||||||||
| 1372 | } | ||||||||
| 1373 | }; | ||||||||
| 1374 | |||||||||
| 1375 | // This function is called by the MonitorDeflationThread to deflate | ||||||||
| 1376 | // ObjectMonitors. It is also called via do_final_audit_and_print_stats() | ||||||||
| 1377 | // by the VMThread. | ||||||||
| 1378 | size_t ObjectSynchronizer::deflate_idle_monitors() { | ||||||||
| 1379 | Thread* current = Thread::current(); | ||||||||
| 1380 | if (current->is_Java_thread()) { | ||||||||
| 1381 | // The async deflation request has been processed. | ||||||||
| 1382 | _last_async_deflation_time_ns = os::javaTimeNanos(); | ||||||||
| 1383 | set_is_async_deflation_requested(false); | ||||||||
| 1384 | } | ||||||||
| 1385 | |||||||||
| 1386 |   LogStreamHandle(Debug, monitorinflation)LogStreamTemplate<LogLevel::Debug, (LogTag::_monitorinflation ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) , (LogTag::__NO_TAG), (LogTag::__NO_TAG)> lsh_debug;  | ||||||||
| 1387 |   LogStreamHandle(Info, monitorinflation)LogStreamTemplate<LogLevel::Info, (LogTag::_monitorinflation ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) , (LogTag::__NO_TAG), (LogTag::__NO_TAG)> lsh_info;  | ||||||||
| 1388 | LogStream* ls = NULL__null; | ||||||||
| 1389 |   if (log_is_enabled(Debug, monitorinflation)(LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG), ( LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag ::__NO_TAG)>::is_level(LogLevel::Debug))) {  | ||||||||
| 1390 | ls = &lsh_debug; | ||||||||
| 1391 |   } else if (log_is_enabled(Info, monitorinflation)(LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG), ( LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag ::__NO_TAG)>::is_level(LogLevel::Info))) {  | ||||||||
| 1392 | ls = &lsh_info; | ||||||||
| 1393 | } | ||||||||
| 1394 | |||||||||
| 1395 | elapsedTimer timer; | ||||||||
| 1396 |   if (ls
 
  | ||||||||
| 1397 | ls->print_cr("begin deflating: in_use_list stats: ceiling=" SIZE_FORMAT"%" "l" "u" ", count=" SIZE_FORMAT"%" "l" "u" ", max=" SIZE_FORMAT"%" "l" "u", | ||||||||
| 1398 | in_use_list_ceiling(), _in_use_list.count(), _in_use_list.max()); | ||||||||
| 1399 | timer.start(); | ||||||||
| 1400 | } | ||||||||
| 1401 | |||||||||
| 1402 | // Deflate some idle ObjectMonitors. | ||||||||
| 1403 | size_t deflated_count = deflate_monitor_list(current, ls, &timer); | ||||||||
| 1404 |   if (deflated_count
 
  | ||||||||
| 1405 | // There are ObjectMonitors that have been deflated or this is the | ||||||||
| 1406 | // final audit and all the remaining ObjectMonitors have been | ||||||||
| 1407 | // deflated, BUT the MonitorDeflationThread blocked for the final | ||||||||
| 1408 | // safepoint during unlinking. | ||||||||
| 1409 | |||||||||
| 1410 | // Unlink deflated ObjectMonitors from the in-use list. | ||||||||
| 1411 | ResourceMark rm; | ||||||||
| 1412 | GrowableArray<ObjectMonitor*> delete_list((int)deflated_count); | ||||||||
| 1413 | size_t unlinked_count = _in_use_list.unlink_deflated(current, ls, &timer, | ||||||||
| 1414 | &delete_list); | ||||||||
| 1415 | if (current->is_Java_thread()) { | ||||||||
| 1416 | if (ls != NULL__null) { | ||||||||
| 1417 | timer.stop(); | ||||||||
| 1418 | ls->print_cr("before handshaking: unlinked_count=" SIZE_FORMAT"%" "l" "u" | ||||||||
| 1419 | ", in_use_list stats: ceiling=" SIZE_FORMAT"%" "l" "u" ", count=" | ||||||||
| 1420 | SIZE_FORMAT"%" "l" "u" ", max=" SIZE_FORMAT"%" "l" "u", | ||||||||
| 1421 | unlinked_count, in_use_list_ceiling(), | ||||||||
| 1422 | _in_use_list.count(), _in_use_list.max()); | ||||||||
| 1423 | } | ||||||||
| 1424 | |||||||||
| 1425 | // A JavaThread needs to handshake in order to safely free the | ||||||||
| 1426 | // ObjectMonitors that were deflated in this cycle. | ||||||||
| 1427 | HandshakeForDeflation hfd_hc; | ||||||||
| 1428 | Handshake::execute(&hfd_hc); | ||||||||
| 1429 | |||||||||
| 1430 | if (ls != NULL__null) { | ||||||||
| 1431 | ls->print_cr("after handshaking: in_use_list stats: ceiling=" | ||||||||
| 1432 | SIZE_FORMAT"%" "l" "u" ", count=" SIZE_FORMAT"%" "l" "u" ", max=" SIZE_FORMAT"%" "l" "u", | ||||||||
| 1433 | in_use_list_ceiling(), _in_use_list.count(), _in_use_list.max()); | ||||||||
| 1434 | timer.start(); | ||||||||
| 1435 | } | ||||||||
| 1436 | } | ||||||||
| 1437 | |||||||||
| 1438 | // After the handshake, safely free the ObjectMonitors that were | ||||||||
| 1439 | // deflated in this cycle. | ||||||||
| 1440 | size_t deleted_count = 0; | ||||||||
| 1441 | for (ObjectMonitor* monitor: delete_list) { | ||||||||
| 1442 | delete monitor; | ||||||||
| 1443 | deleted_count++; | ||||||||
| 1444 | |||||||||
| 1445 | if (current->is_Java_thread()) { | ||||||||
| 1446 | // A JavaThread must check for a safepoint/handshake and honor it. | ||||||||
| 1447 | chk_for_block_req(JavaThread::cast(current), "deletion", "deleted_count", | ||||||||
| 1448 | deleted_count, ls, &timer); | ||||||||
| 1449 | } | ||||||||
| 1450 | } | ||||||||
| 1451 | } | ||||||||
| 1452 | |||||||||
| 1453 | if (ls != NULL__null) { | ||||||||
| 1454 | timer.stop(); | ||||||||
| 1455 |     if (deflated_count != 0 || log_is_enabled(Debug, monitorinflation)(LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG), ( LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag ::__NO_TAG)>::is_level(LogLevel::Debug))) {  | ||||||||
| 1456 | ls->print_cr("deflated " SIZE_FORMAT"%" "l" "u" " monitors in %3.7f secs", | ||||||||
| 1457 | deflated_count, timer.seconds()); | ||||||||
| 1458 | } | ||||||||
| 1459 | ls->print_cr("end deflating: in_use_list stats: ceiling=" SIZE_FORMAT"%" "l" "u" ", count=" SIZE_FORMAT"%" "l" "u" ", max=" SIZE_FORMAT"%" "l" "u", | ||||||||
| 1460 | in_use_list_ceiling(), _in_use_list.count(), _in_use_list.max()); | ||||||||
| 1461 | } | ||||||||
| 1462 | |||||||||
| 1463 |   OM_PERFDATA_OP(MonExtant, set_value(_in_use_list.count()))do { if (ObjectMonitor::_sync_MonExtant != __null && PerfDataManager ::has_PerfData()) { ObjectMonitor::_sync_MonExtant->set_value (_in_use_list.count()); } } while (0);  | ||||||||
| 1464 |   OM_PERFDATA_OP(Deflations, inc(deflated_count))do { if (ObjectMonitor::_sync_Deflations != __null && PerfDataManager::has_PerfData()) { ObjectMonitor::_sync_Deflations ->inc(deflated_count); } } while (0);  | ||||||||
| 1465 | |||||||||
| 1466 | GVars.stw_random = os::random(); | ||||||||
| 1467 | |||||||||
| 1468 | if (deflated_count != 0) { | ||||||||
| 1469 | _no_progress_cnt = 0; | ||||||||
| 1470 | } else { | ||||||||
| 1471 | _no_progress_cnt++; | ||||||||
| 1472 | } | ||||||||
| 1473 | |||||||||
| 1474 | return deflated_count; | ||||||||
| 1475 | } | ||||||||
| 1476 | |||||||||
| 1477 | // Monitor cleanup on JavaThread::exit | ||||||||
| 1478 | |||||||||
| 1479 | // Iterate through monitor cache and attempt to release thread's monitors | ||||||||
| 1480 | class ReleaseJavaMonitorsClosure: public MonitorClosure { | ||||||||
| 1481 | private: | ||||||||
| 1482 | JavaThread* _thread; | ||||||||
| 1483 | |||||||||
| 1484 | public: | ||||||||
| 1485 | ReleaseJavaMonitorsClosure(JavaThread* thread) : _thread(thread) {} | ||||||||
| 1486 | void do_monitor(ObjectMonitor* mid) { | ||||||||
| 1487 | (void)mid->complete_exit(_thread); | ||||||||
| 1488 | } | ||||||||
| 1489 | }; | ||||||||
| 1490 | |||||||||
| 1491 | // Release all inflated monitors owned by current thread. Lightweight monitors are | ||||||||
| 1492 | // ignored. This is meant to be called during JNI thread detach which assumes | ||||||||
| 1493 | // all remaining monitors are heavyweight. All exceptions are swallowed. | ||||||||
| 1494 | // Scanning the extant monitor list can be time consuming. | ||||||||
| 1495 | // A simple optimization is to add a per-thread flag that indicates a thread | ||||||||
| 1496 | // called jni_monitorenter() during its lifetime. | ||||||||
| 1497 | // | ||||||||
| 1498 | // Instead of NoSafepointVerifier it might be cheaper to | ||||||||
| 1499 | // use an idiom of the form: | ||||||||
| 1500 | // auto int tmp = SafepointSynchronize::_safepoint_counter ; | ||||||||
| 1501 | // <code that must not run at safepoint> | ||||||||
| 1502 | // guarantee (((tmp ^ _safepoint_counter) | (tmp & 1)) == 0) ; | ||||||||
| 1503 | // Since the tests are extremely cheap we could leave them enabled | ||||||||
| 1504 | // for normal product builds. | ||||||||
| 1505 | |||||||||
| 1506 | void ObjectSynchronizer::release_monitors_owned_by_thread(JavaThread* current) { | ||||||||
| 1507 |   assert(current == JavaThread::current(), "must be current Java thread")do { if (!(current == JavaThread::current())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 1507, "assert(" "current == JavaThread::current()" ") failed" , "must be current Java thread"); ::breakpoint(); } } while ( 0);  | ||||||||
| 1508 | NoSafepointVerifier nsv; | ||||||||
| 1509 | ReleaseJavaMonitorsClosure rjmc(current); | ||||||||
| 1510 | ObjectSynchronizer::monitors_iterate(&rjmc, current); | ||||||||
| 1511 |   assert(!current->has_pending_exception(), "Should not be possible")do { if (!(!current->has_pending_exception())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 1511, "assert(" "!current->has_pending_exception()" ") failed" , "Should not be possible"); ::breakpoint(); } } while (0);  | ||||||||
| 1512 | current->clear_pending_exception(); | ||||||||
| 1513 | } | ||||||||
| 1514 | |||||||||
| 1515 | const char* ObjectSynchronizer::inflate_cause_name(const InflateCause cause) { | ||||||||
| 1516 | switch (cause) { | ||||||||
| 1517 | case inflate_cause_vm_internal: return "VM Internal"; | ||||||||
| 1518 | case inflate_cause_monitor_enter: return "Monitor Enter"; | ||||||||
| 1519 | case inflate_cause_wait: return "Monitor Wait"; | ||||||||
| 1520 | case inflate_cause_notify: return "Monitor Notify"; | ||||||||
| 1521 | case inflate_cause_hash_code: return "Monitor Hash Code"; | ||||||||
| 1522 | case inflate_cause_jni_enter: return "JNI Monitor Enter"; | ||||||||
| 1523 | case inflate_cause_jni_exit: return "JNI Monitor Exit"; | ||||||||
| 1524 | default: | ||||||||
| 1525 |       ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here( "/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 1525); ::breakpoint(); } while (0);  | ||||||||
| 1526 | } | ||||||||
| 1527 | return "Unknown"; | ||||||||
| 1528 | } | ||||||||
| 1529 | |||||||||
| 1530 | //------------------------------------------------------------------------------ | ||||||||
| 1531 | // Debugging code | ||||||||
| 1532 | |||||||||
| 1533 | u_char* ObjectSynchronizer::get_gvars_addr() { | ||||||||
| 1534 | return (u_char*)&GVars; | ||||||||
| 1535 | } | ||||||||
| 1536 | |||||||||
| 1537 | u_char* ObjectSynchronizer::get_gvars_hc_sequence_addr() { | ||||||||
| 1538 | return (u_char*)&GVars.hc_sequence; | ||||||||
| 1539 | } | ||||||||
| 1540 | |||||||||
| 1541 | size_t ObjectSynchronizer::get_gvars_size() { | ||||||||
| 1542 | return sizeof(SharedGlobals); | ||||||||
| 1543 | } | ||||||||
| 1544 | |||||||||
| 1545 | u_char* ObjectSynchronizer::get_gvars_stw_random_addr() { | ||||||||
| 1546 | return (u_char*)&GVars.stw_random; | ||||||||
| 1547 | } | ||||||||
| 1548 | |||||||||
| 1549 | // Do the final audit and print of ObjectMonitor stats; must be done | ||||||||
| 1550 | // by the VMThread at VM exit time. | ||||||||
| 1551 | void ObjectSynchronizer::do_final_audit_and_print_stats() { | ||||||||
| 1552 |   assert(Thread::current()->is_VM_thread(), "sanity check")do { if (!(Thread::current()->is_VM_thread())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 1552, "assert(" "Thread::current()->is_VM_thread()" ") failed" , "sanity check"); ::breakpoint(); } } while (0);  | ||||||||
  | |||||||||
| 1553 | |||||||||
| 1554 | if (is_final_audit()) { // Only do the audit once. | ||||||||
| 1555 | return; | ||||||||
| 1556 | } | ||||||||
| 1557 | set_is_final_audit(); | ||||||||
| 1558 | |||||||||
| 1559 |   if (log_is_enabled(Info, monitorinflation)(LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG), ( LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag ::__NO_TAG)>::is_level(LogLevel::Info))) {  | ||||||||
| 1560 | // Do a deflation in order to reduce the in-use monitor population | ||||||||
| 1561 | // that is reported by ObjectSynchronizer::log_in_use_monitor_details() | ||||||||
| 1562 | // which is called by ObjectSynchronizer::audit_and_print_stats(). | ||||||||
| 1563 | while (ObjectSynchronizer::deflate_idle_monitors() != 0) { | ||||||||
| 1564 | ; // empty | ||||||||
| 1565 | } | ||||||||
| 1566 | // The other audit_and_print_stats() call is done at the Debug | ||||||||
| 1567 | // level at a safepoint in ObjectSynchronizer::do_safepoint_work(). | ||||||||
| 1568 | ObjectSynchronizer::audit_and_print_stats(true /* on_exit */); | ||||||||
| 1569 | } | ||||||||
| 1570 | } | ||||||||
| 1571 | |||||||||
| 1572 | // This function can be called at a safepoint or it can be called when | ||||||||
| 1573 | // we are trying to exit the VM. When we are trying to exit the VM, the | ||||||||
| 1574 | // list walker functions can run in parallel with the other list | ||||||||
| 1575 | // operations so spin-locking is used for safety. | ||||||||
| 1576 | // | ||||||||
| 1577 | // Calls to this function can be added in various places as a debugging | ||||||||
| 1578 | // aid; pass 'true' for the 'on_exit' parameter to have in-use monitor | ||||||||
| 1579 | // details logged at the Info level and 'false' for the 'on_exit' | ||||||||
| 1580 | // parameter to have in-use monitor details logged at the Trace level. | ||||||||
| 1581 | // | ||||||||
| 1582 | void ObjectSynchronizer::audit_and_print_stats(bool on_exit) { | ||||||||
| 1583 |   assert(on_exit || SafepointSynchronize::is_at_safepoint(), "invariant")do { if (!(on_exit || SafepointSynchronize::is_at_safepoint() )) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 1583, "assert(" "on_exit || SafepointSynchronize::is_at_safepoint()" ") failed", "invariant"); ::breakpoint(); } } while (0);  | ||||||||
| 1584 | |||||||||
| 1585 |   LogStreamHandle(Debug, monitorinflation)LogStreamTemplate<LogLevel::Debug, (LogTag::_monitorinflation ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) , (LogTag::__NO_TAG), (LogTag::__NO_TAG)> lsh_debug;  | ||||||||
| 1586 |   LogStreamHandle(Info, monitorinflation)LogStreamTemplate<LogLevel::Info, (LogTag::_monitorinflation ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) , (LogTag::__NO_TAG), (LogTag::__NO_TAG)> lsh_info;  | ||||||||
| 1587 |   LogStreamHandle(Trace, monitorinflation)LogStreamTemplate<LogLevel::Trace, (LogTag::_monitorinflation ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) , (LogTag::__NO_TAG), (LogTag::__NO_TAG)> lsh_trace;  | ||||||||
| 1588 | LogStream* ls = NULL__null; | ||||||||
| 1589 |   if (log_is_enabled(Trace, monitorinflation)(LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG), ( LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag ::__NO_TAG)>::is_level(LogLevel::Trace))) {  | ||||||||
| 1590 | ls = &lsh_trace; | ||||||||
| 1591 |   } else if (log_is_enabled(Debug, monitorinflation)(LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG), ( LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag ::__NO_TAG)>::is_level(LogLevel::Debug))) {  | ||||||||
| 1592 | ls = &lsh_debug; | ||||||||
| 1593 |   } else if (log_is_enabled(Info, monitorinflation)(LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG), ( LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag ::__NO_TAG)>::is_level(LogLevel::Info))) {  | ||||||||
| 1594 | ls = &lsh_info; | ||||||||
| 1595 | } | ||||||||
| 1596 |   assert(ls != NULL, "sanity check")do { if (!(ls != __null)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 1596, "assert(" "ls != __null" ") failed", "sanity check"); ::breakpoint(); } } while (0);  | ||||||||
| 1597 | |||||||||
| 1598 | int error_cnt = 0; | ||||||||
| 1599 | |||||||||
| 1600 | ls->print_cr("Checking in_use_list:"); | ||||||||
| 1601 | chk_in_use_list(ls, &error_cnt); | ||||||||
| 1602 | |||||||||
| 1603 | if (error_cnt == 0) { | ||||||||
| 1604 | ls->print_cr("No errors found in in_use_list checks."); | ||||||||
| 1605 | } else { | ||||||||
| 1606 |     log_error(monitorinflation)(!(LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG) , (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::is_level(LogLevel::Error))) ? (void) 0 : LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) , (LogTag::__NO_TAG)>::write<LogLevel::Error>("found in_use_list errors: error_cnt=%d", error_cnt);  | ||||||||
| 1607 | } | ||||||||
| 1608 | |||||||||
| 1609 |   if ((on_exit && log_is_enabled(Info, monitorinflation)(LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG), ( LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag ::__NO_TAG)>::is_level(LogLevel::Info))) ||  | ||||||||
| 1610 |       (!on_exit && log_is_enabled(Trace, monitorinflation)(LogImpl<(LogTag::_monitorinflation), (LogTag::__NO_TAG), ( LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag ::__NO_TAG)>::is_level(LogLevel::Trace)))) {  | ||||||||
| 1611 | // When exiting this log output is at the Info level. When called | ||||||||
| 1612 | // at a safepoint, this log output is at the Trace level since | ||||||||
| 1613 | // there can be a lot of it. | ||||||||
| 1614 | log_in_use_monitor_details(ls); | ||||||||
| 1615 | } | ||||||||
| 1616 | |||||||||
| 1617 | ls->flush(); | ||||||||
| 1618 | |||||||||
| 1619 |   guarantee(error_cnt == 0, "ERROR: found monitor list errors: error_cnt=%d", error_cnt)do { if (!(error_cnt == 0)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/synchronizer.cpp" , 1619, "guarantee(" "error_cnt == 0" ") failed", "ERROR: found monitor list errors: error_cnt=%d" , error_cnt); ::breakpoint(); } } while (0);  | ||||||||
| 1620 | } | ||||||||
| 1621 | |||||||||
| 1622 | // Check the in_use_list; log the results of the checks. | ||||||||
| 1623 | void ObjectSynchronizer::chk_in_use_list(outputStream* out, int *error_cnt_p) { | ||||||||
| 1624 | size_t l_in_use_count = _in_use_list.count(); | ||||||||
| 1625 | size_t l_in_use_max = _in_use_list.max(); | ||||||||
| 1626 | out->print_cr("count=" SIZE_FORMAT"%" "l" "u" ", max=" SIZE_FORMAT"%" "l" "u", l_in_use_count, | ||||||||
| 1627 | l_in_use_max); | ||||||||
| 1628 | |||||||||
| 1629 | size_t ck_in_use_count = 0; | ||||||||
| 1630 | MonitorList::Iterator iter = _in_use_list.iterator(); | ||||||||
| 1631 | while (iter.has_next()) { | ||||||||
| 1632 | ObjectMonitor* mid = iter.next(); | ||||||||
| 1633 | chk_in_use_entry(mid, out, error_cnt_p); | ||||||||
| 1634 | ck_in_use_count++; | ||||||||
| 1635 | } | ||||||||
| 1636 | |||||||||
| 1637 | if (l_in_use_count == ck_in_use_count) { | ||||||||
| 1638 | out->print_cr("in_use_count=" SIZE_FORMAT"%" "l" "u" " equals ck_in_use_count=" | ||||||||
| 1639 | SIZE_FORMAT"%" "l" "u", l_in_use_count, ck_in_use_count); | ||||||||
| 1640 | } else { | ||||||||
| 1641 | out->print_cr("WARNING: in_use_count=" SIZE_FORMAT"%" "l" "u" " is not equal to " | ||||||||
| 1642 | "ck_in_use_count=" SIZE_FORMAT"%" "l" "u", l_in_use_count, | ||||||||
| 1643 | ck_in_use_count); | ||||||||
| 1644 | } | ||||||||
| 1645 | |||||||||
| 1646 | size_t ck_in_use_max = _in_use_list.max(); | ||||||||
| 1647 | if (l_in_use_max == ck_in_use_max) { | ||||||||
| 1648 | out->print_cr("in_use_max=" SIZE_FORMAT"%" "l" "u" " equals ck_in_use_max=" | ||||||||
| 1649 | SIZE_FORMAT"%" "l" "u", l_in_use_max, ck_in_use_max); | ||||||||
| 1650 | } else { | ||||||||
| 1651 | out->print_cr("WARNING: in_use_max=" SIZE_FORMAT"%" "l" "u" " is not equal to " | ||||||||
| 1652 | "ck_in_use_max=" SIZE_FORMAT"%" "l" "u", l_in_use_max, ck_in_use_max); | ||||||||
| 1653 | } | ||||||||
| 1654 | } | ||||||||
| 1655 | |||||||||
| 1656 | // Check an in-use monitor entry; log any errors. | ||||||||
| 1657 | void ObjectSynchronizer::chk_in_use_entry(ObjectMonitor* n, outputStream* out, | ||||||||
| 1658 | int* error_cnt_p) { | ||||||||
| 1659 | if (n->owner_is_DEFLATER_MARKER()) { | ||||||||
| 1660 | // This should not happen, but if it does, it is not fatal. | ||||||||
| 1661 | out->print_cr("WARNING: monitor=" INTPTR_FORMAT"0x%016" "l" "x" ": in-use monitor is " | ||||||||
| 1662 | "deflated.", p2i(n)); | ||||||||
| 1663 | return; | ||||||||
| 1664 | } | ||||||||
| 1665 | if (n->header().value() == 0) { | ||||||||
| 1666 | out->print_cr("ERROR: monitor=" INTPTR_FORMAT"0x%016" "l" "x" ": in-use monitor must " | ||||||||
| 1667 | "have non-NULL _header field.", p2i(n)); | ||||||||
| 1668 | *error_cnt_p = *error_cnt_p + 1; | ||||||||
| 1669 | } | ||||||||
| 1670 | const oop obj = n->object_peek(); | ||||||||
| 1671 | if (obj != NULL__null) { | ||||||||
| 1672 | const markWord mark = obj->mark(); | ||||||||
| 1673 | if (!mark.has_monitor()) { | ||||||||
| 1674 | out->print_cr("ERROR: monitor=" INTPTR_FORMAT"0x%016" "l" "x" ": in-use monitor's " | ||||||||
| 1675 | "object does not think it has a monitor: obj=" | ||||||||
| 1676 | INTPTR_FORMAT"0x%016" "l" "x" ", mark=" INTPTR_FORMAT"0x%016" "l" "x", p2i(n), | ||||||||
| 1677 | p2i(obj), mark.value()); | ||||||||
| 1678 | *error_cnt_p = *error_cnt_p + 1; | ||||||||
| 1679 | } | ||||||||
| 1680 | ObjectMonitor* const obj_mon = mark.monitor(); | ||||||||
| 1681 | if (n != obj_mon) { | ||||||||
| 1682 | out->print_cr("ERROR: monitor=" INTPTR_FORMAT"0x%016" "l" "x" ": in-use monitor's " | ||||||||
| 1683 | "object does not refer to the same monitor: obj=" | ||||||||
| 1684 | INTPTR_FORMAT"0x%016" "l" "x" ", mark=" INTPTR_FORMAT"0x%016" "l" "x" ", obj_mon=" | ||||||||
| 1685 | INTPTR_FORMAT"0x%016" "l" "x", p2i(n), p2i(obj), mark.value(), p2i(obj_mon)); | ||||||||
| 1686 | *error_cnt_p = *error_cnt_p + 1; | ||||||||
| 1687 | } | ||||||||
| 1688 | } | ||||||||
| 1689 | } | ||||||||
| 1690 | |||||||||
| 1691 | // Log details about ObjectMonitors on the in_use_list. The 'BHL' | ||||||||
| 1692 | // flags indicate why the entry is in-use, 'object' and 'object type' | ||||||||
| 1693 | // indicate the associated object and its type. | ||||||||
| 1694 | void ObjectSynchronizer::log_in_use_monitor_details(outputStream* out) { | ||||||||
| 1695 | stringStream ss; | ||||||||
| 1696 | if (_in_use_list.count() > 0) { | ||||||||
| 1697 | out->print_cr("In-use monitor info:"); | ||||||||
| 1698 | out->print_cr("(B -> is_busy, H -> has hash code, L -> lock status)"); | ||||||||
| 1699 | out->print_cr("%18s %s %18s %18s", | ||||||||
| 1700 | "monitor", "BHL", "object", "object type"); | ||||||||
| 1701 | out->print_cr("================== === ================== =================="); | ||||||||
| 1702 | MonitorList::Iterator iter = _in_use_list.iterator(); | ||||||||
| 1703 | while (iter.has_next()) { | ||||||||
| 1704 | ObjectMonitor* mid = iter.next(); | ||||||||
| 1705 | const oop obj = mid->object_peek(); | ||||||||
| 1706 | const markWord mark = mid->header(); | ||||||||
| 1707 | ResourceMark rm; | ||||||||
| 1708 | out->print(INTPTR_FORMAT"0x%016" "l" "x" " %d%d%d " INTPTR_FORMAT"0x%016" "l" "x" " %s", p2i(mid), | ||||||||
| 1709 | mid->is_busy(), mark.hash() != 0, mid->owner() != NULL__null, | ||||||||
| 1710 | p2i(obj), obj == NULL__null ? "" : obj->klass()->external_name()); | ||||||||
| 1711 | if (mid->is_busy()) { | ||||||||
| 1712 | out->print(" (%s)", mid->is_busy_to_string(&ss)); | ||||||||
| 1713 | ss.reset(); | ||||||||
| 1714 | } | ||||||||
| 1715 | out->cr(); | ||||||||
| 1716 | } | ||||||||
| 1717 | } | ||||||||
| 1718 | |||||||||
| 1719 | out->flush(); | ||||||||
| 1720 | } | 
| 1 | /* | 
| 2 | * Copyright (c) 1998, 2021, 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 "logging/log.hpp" | 
| 31 | #include "oops/access.inline.hpp" | 
| 32 | #include "runtime/atomic.hpp" | 
| 33 | #include "runtime/synchronizer.hpp" | 
| 34 | |
| 35 | inline intptr_t ObjectMonitor::is_entered(JavaThread* current) const { | 
| 36 | void* owner = owner_raw(); | 
| 37 | if (current == owner || current->is_lock_owned((address)owner)) { | 
| 38 | return 1; | 
| 39 | } | 
| 40 | return 0; | 
| 41 | } | 
| 42 | |
| 43 | inline markWord ObjectMonitor::header() const { | 
| 44 | return Atomic::load(&_header); | 
| 45 | } | 
| 46 | |
| 47 | inline volatile markWord* ObjectMonitor::header_addr() { | 
| 48 | return &_header; | 
| 49 | } | 
| 50 | |
| 51 | inline void ObjectMonitor::set_header(markWord hdr) { | 
| 52 | Atomic::store(&_header, hdr); | 
| 53 | } | 
| 54 | |
| 55 | inline int ObjectMonitor::waiters() const { | 
| 56 | return _waiters; | 
| 57 | } | 
| 58 | |
| 59 | // Returns NULL if DEFLATER_MARKER is observed. | 
| 60 | inline void* ObjectMonitor::owner() const { | 
| 61 | void* owner = owner_raw(); | 
| 62 | return owner != DEFLATER_MARKERreinterpret_cast<void*>(-1) ? owner : NULL__null; | 
| 63 | } | 
| 64 | |
| 65 | inline void* ObjectMonitor::owner_raw() const { | 
| 66 | return Atomic::load(&_owner); | 
| 67 | } | 
| 68 | |
| 69 | // Returns true if owner field == DEFLATER_MARKER and false otherwise. | 
| 70 | // This accessor is called when we really need to know if the owner | 
| 71 | // field == DEFLATER_MARKER and any non-NULL value won't do the trick. | 
| 72 | inline bool ObjectMonitor::owner_is_DEFLATER_MARKER() const { | 
| 73 | return owner_raw() == DEFLATER_MARKERreinterpret_cast<void*>(-1); | 
| 74 | } | 
| 75 | |
| 76 | // Returns true if 'this' is being async deflated and false otherwise. | 
| 77 | inline bool ObjectMonitor::is_being_async_deflated() { | 
| 78 | return contentions() < 0; | 
| 79 | } | 
| 80 | |
| 81 | // Return number of threads contending for this monitor. | 
| 82 | inline int ObjectMonitor::contentions() const { | 
| 83 | return Atomic::load(&_contentions); | 
| 84 | } | 
| 85 | |
| 86 | // Add value to the contentions field. | 
| 87 | inline void ObjectMonitor::add_to_contentions(int value) { | 
| 88 | Atomic::add(&_contentions, value); | 
| 89 | } | 
| 90 | |
| 91 | // Clear _owner field; current value must match old_value. | 
| 92 | inline void ObjectMonitor::release_clear_owner(void* old_value) { | 
| 93 | #ifdef ASSERT1 | 
| 94 | void* prev = Atomic::load(&_owner); | 
| 95 |   assert(prev == old_value, "unexpected prev owner=" INTPTR_FORMATdo { if (!(prev == old_value)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/objectMonitor.inline.hpp" , 96, "assert(" "prev == old_value" ") failed", "unexpected prev owner=" "0x%016" "l" "x" ", expected=" "0x%016" "l" "x", p2i(prev), p2i (old_value)); ::breakpoint(); } } while (0)  | 
| 96 |          ", expected=" INTPTR_FORMAT, p2i(prev), p2i(old_value))do { if (!(prev == old_value)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/objectMonitor.inline.hpp" , 96, "assert(" "prev == old_value" ") failed", "unexpected prev owner=" "0x%016" "l" "x" ", expected=" "0x%016" "l" "x", p2i(prev), p2i (old_value)); ::breakpoint(); } } while (0);  | 
| 97 | #endif | 
| 98 | Atomic::release_store(&_owner, (void*)NULL__null); | 
| 99 |   log_trace(monitorinflation, owner)(!(LogImpl<(LogTag::_monitorinflation), (LogTag::_owner), ( LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag ::__NO_TAG)>::is_level(LogLevel::Trace))) ? (void)0 : LogImpl <(LogTag::_monitorinflation), (LogTag::_owner), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::write<LogLevel::Trace>("release_clear_owner(): mid="  | 
| 100 | INTPTR_FORMAT"0x%016" "l" "x" ", old_value=" INTPTR_FORMAT"0x%016" "l" "x", | 
| 101 | p2i(this), p2i(old_value)); | 
| 102 | } | 
| 103 | |
| 104 | // Simply set _owner field to new_value; current value must match old_value. | 
| 105 | // (Simple means no memory sync needed.) | 
| 106 | inline void ObjectMonitor::set_owner_from(void* old_value, void* new_value) { | 
| 107 | #ifdef ASSERT1 | 
| 108 | void* prev = Atomic::load(&_owner); | 
| 109 |   assert(prev == old_value, "unexpected prev owner=" INTPTR_FORMATdo { if (!(prev == old_value)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/objectMonitor.inline.hpp" , 110, "assert(" "prev == old_value" ") failed", "unexpected prev owner=" "0x%016" "l" "x" ", expected=" "0x%016" "l" "x", p2i(prev), p2i (old_value)); ::breakpoint(); } } while (0)  | 
| 110 |          ", expected=" INTPTR_FORMAT, p2i(prev), p2i(old_value))do { if (!(prev == old_value)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/objectMonitor.inline.hpp" , 110, "assert(" "prev == old_value" ") failed", "unexpected prev owner=" "0x%016" "l" "x" ", expected=" "0x%016" "l" "x", p2i(prev), p2i (old_value)); ::breakpoint(); } } while (0);  | 
| 111 | #endif | 
| 112 | Atomic::store(&_owner, new_value); | 
| 113 |   log_trace(monitorinflation, owner)(!(LogImpl<(LogTag::_monitorinflation), (LogTag::_owner), ( LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag ::__NO_TAG)>::is_level(LogLevel::Trace))) ? (void)0 : LogImpl <(LogTag::_monitorinflation), (LogTag::_owner), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::write<LogLevel::Trace>("set_owner_from(): mid="  | 
| 114 | INTPTR_FORMAT"0x%016" "l" "x" ", old_value=" INTPTR_FORMAT"0x%016" "l" "x" | 
| 115 | ", new_value=" INTPTR_FORMAT"0x%016" "l" "x", p2i(this), | 
| 116 | p2i(old_value), p2i(new_value)); | 
| 117 | } | 
| 118 | |
| 119 | // Simply set _owner field to self; current value must match basic_lock_p. | 
| 120 | inline void ObjectMonitor::set_owner_from_BasicLock(void* basic_lock_p, JavaThread* current) { | 
| 121 | #ifdef ASSERT1 | 
| 122 | void* prev = Atomic::load(&_owner); | 
| 123 |   assert(prev == basic_lock_p, "unexpected prev owner=" INTPTR_FORMATdo { if (!(prev == basic_lock_p)) { (*g_assert_poison) = 'X'; ; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/objectMonitor.inline.hpp" , 124, "assert(" "prev == basic_lock_p" ") failed", "unexpected prev owner=" "0x%016" "l" "x" ", expected=" "0x%016" "l" "x", p2i(prev), p2i (basic_lock_p)); ::breakpoint(); } } while (0)  | 
| 124 |          ", expected=" INTPTR_FORMAT, p2i(prev), p2i(basic_lock_p))do { if (!(prev == basic_lock_p)) { (*g_assert_poison) = 'X'; ; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/objectMonitor.inline.hpp" , 124, "assert(" "prev == basic_lock_p" ") failed", "unexpected prev owner=" "0x%016" "l" "x" ", expected=" "0x%016" "l" "x", p2i(prev), p2i (basic_lock_p)); ::breakpoint(); } } while (0);  | 
| 125 | #endif | 
| 126 | // Non-null owner field to non-null owner field is safe without | 
| 127 | // cmpxchg() as long as all readers can tolerate either flavor. | 
| 128 | Atomic::store(&_owner, current); | 
| 129 |   log_trace(monitorinflation, owner)(!(LogImpl<(LogTag::_monitorinflation), (LogTag::_owner), ( LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag ::__NO_TAG)>::is_level(LogLevel::Trace))) ? (void)0 : LogImpl <(LogTag::_monitorinflation), (LogTag::_owner), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::write<LogLevel::Trace>("set_owner_from_BasicLock(): mid="  | 
| 130 | INTPTR_FORMAT"0x%016" "l" "x" ", basic_lock_p=" | 
| 131 | INTPTR_FORMAT"0x%016" "l" "x" ", new_value=" INTPTR_FORMAT"0x%016" "l" "x", | 
| 132 | p2i(this), p2i(basic_lock_p), p2i(current)); | 
| 133 | } | 
| 134 | |
| 135 | // Try to set _owner field to new_value if the current value matches | 
| 136 | // old_value. Otherwise, does not change the _owner field. Returns | 
| 137 | // the prior value of the _owner field. | 
| 138 | inline void* ObjectMonitor::try_set_owner_from(void* old_value, void* new_value) { | 
| 139 | void* prev = Atomic::cmpxchg(&_owner, old_value, new_value); | 
| 140 | if (prev == old_value) { | 
| 141 |     log_trace(monitorinflation, owner)(!(LogImpl<(LogTag::_monitorinflation), (LogTag::_owner), ( LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag ::__NO_TAG)>::is_level(LogLevel::Trace))) ? (void)0 : LogImpl <(LogTag::_monitorinflation), (LogTag::_owner), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::write<LogLevel::Trace>("try_set_owner_from(): mid="  | 
| 142 | INTPTR_FORMAT"0x%016" "l" "x" ", prev=" INTPTR_FORMAT"0x%016" "l" "x" | 
| 143 | ", new=" INTPTR_FORMAT"0x%016" "l" "x", p2i(this), | 
| 144 | p2i(prev), p2i(new_value)); | 
| 145 | } | 
| 146 | return prev; | 
| 147 | } | 
| 148 | |
| 149 | // The _next_om field can be concurrently read and modified so we | 
| 150 | // use Atomic operations to disable compiler optimizations that | 
| 151 | // might try to elide loading and/or storing this field. | 
| 152 | |
| 153 | // Simply get _next_om field. | 
| 154 | inline ObjectMonitor* ObjectMonitor::next_om() const { | 
| 155 | return Atomic::load(&_next_om); | 
| 156 | } | 
| 157 | |
| 158 | // Get _next_om field with acquire semantics. | 
| 159 | inline ObjectMonitor* ObjectMonitor::next_om_acquire() const { | 
| 160 | return Atomic::load_acquire(&_next_om); | 
| 161 | } | 
| 162 | |
| 163 | // Simply set _next_om field to new_value. | 
| 164 | inline void ObjectMonitor::set_next_om(ObjectMonitor* new_value) { | 
| 165 | Atomic::store(&_next_om, new_value); | 
| 166 | } | 
| 167 | |
| 168 | // Set _next_om field to new_value with release semantics. | 
| 169 | inline void ObjectMonitor::release_set_next_om(ObjectMonitor* new_value) { | 
| 170 | Atomic::release_store(&_next_om, new_value); | 
| 171 | } | 
| 172 | |
| 173 | // Try to set _next_om field to new_value if the current value matches | 
| 174 | // old_value. Otherwise, does not change the _next_om field. Returns | 
| 175 | // the prior value of the _next_om field. | 
| 176 | inline ObjectMonitor* ObjectMonitor::try_set_next_om(ObjectMonitor* old_value, ObjectMonitor* new_value) { | 
| 177 | return Atomic::cmpxchg(&_next_om, old_value, new_value); | 
| 178 | } | 
| 179 | |
| 180 | #endif // SHARE_RUNTIME_OBJECTMONITOR_INLINE_HPP |