annotate hotspot/src/share/vm/runtime/objectMonitor.hpp @ 39702:ea7e9375bb93

8068592: Remove unused code in objectMonitor.hpp Reviewed-by: dholmes, redestad, gthornbr
author dcubed
date Thu, 07 Jul 2016 14:58:17 -0700
parents b7b2407bc7e5
children c871e0f8b02a
rev   line source
duke@1 1 /*
dcubed@39702 2 * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
duke@1 7 * published by the Free Software Foundation.
duke@1 8 *
duke@1 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 13 * accompanied this code).
duke@1 14 *
duke@1 15 * You should have received a copy of the GNU General Public License version
duke@1 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 18 *
trims@5547 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@5547 20 * or visit www.oracle.com if you need additional information or have any
trims@5547 21 * questions.
duke@1 22 *
duke@1 23 */
duke@1 24
stefank@7397 25 #ifndef SHARE_VM_RUNTIME_OBJECTMONITOR_HPP
stefank@7397 26 #define SHARE_VM_RUNTIME_OBJECTMONITOR_HPP
stefank@7397 27
dcubed@27165 28 #include "memory/padded.hpp"
stefank@7397 29 #include "runtime/os.hpp"
stefank@7408 30 #include "runtime/park.hpp"
stefank@7397 31 #include "runtime/perfData.hpp"
stefank@7397 32
acorn@6975 33 // ObjectWaiter serves as a "proxy" or surrogate thread.
acorn@6975 34 // TODO-FIXME: Eliminate ObjectWaiter and use the thread-specific
acorn@6975 35 // ParkEvent instead. Beware, however, that the JVMTI code
acorn@6975 36 // knows about ObjectWaiters, so we'll have to reconcile that code.
acorn@6975 37 // See next_waiter(), first_waiter(), etc.
acorn@6975 38
acorn@6975 39 class ObjectWaiter : public StackObj {
acorn@6975 40 public:
dcubed@25064 41 enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ };
dcubed@25064 42 enum Sorted { PREPEND, APPEND, SORTED };
acorn@6975 43 ObjectWaiter * volatile _next;
acorn@6975 44 ObjectWaiter * volatile _prev;
acorn@6975 45 Thread* _thread;
sla@18025 46 jlong _notifier_tid;
acorn@6975 47 ParkEvent * _event;
dcubed@25064 48 volatile int _notified;
dcubed@25064 49 volatile TStates TState;
dcubed@25064 50 Sorted _Sorted; // List placement disposition
dcubed@25064 51 bool _active; // Contention monitoring is enabled
acorn@6975 52 public:
acorn@6975 53 ObjectWaiter(Thread* thread);
acorn@6975 54
acorn@6975 55 void wait_reenter_begin(ObjectMonitor *mon);
acorn@6975 56 void wait_reenter_end(ObjectMonitor *mon);
acorn@6975 57 };
acorn@6975 58
sla@18025 59 // forward declaration to avoid include tracing.hpp
sla@18025 60 class EventJavaMonitorWait;
sla@18025 61
dcubed@27165 62 // The ObjectMonitor class implements the heavyweight version of a
dcubed@27165 63 // JavaMonitor. The lightweight BasicLock/stack lock version has been
dcubed@27165 64 // inflated into an ObjectMonitor. This inflation is typically due to
dcubed@27165 65 // contention or use of Object.wait().
duke@1 66 //
dcubed@27165 67 // WARNING: This is a very sensitive and fragile class. DO NOT make any
dcubed@27165 68 // changes unless you are fully aware of the underlying semantics.
dcubed@27165 69 //
dcubed@27165 70 // Class JvmtiRawMonitor currently inherits from ObjectMonitor so
dcubed@27165 71 // changes in this class must be careful to not break JvmtiRawMonitor.
dcubed@27165 72 // These two subsystems should be separated.
dcubed@27165 73 //
dcubed@27165 74 // ObjectMonitor Layout Overview/Highlights/Restrictions:
dcubed@27165 75 //
dcubed@27165 76 // - The _header field must be at offset 0 because the displaced header
dcubed@27165 77 // from markOop is stored there. We do not want markOop.hpp to include
dcubed@27165 78 // ObjectMonitor.hpp to avoid exposing ObjectMonitor everywhere. This
dcubed@27165 79 // means that ObjectMonitor cannot inherit from any other class nor can
dcubed@27165 80 // it use any virtual member functions. This restriction is critical to
dcubed@27165 81 // the proper functioning of the VM.
dcubed@27165 82 // - The _header and _owner fields should be separated by enough space
dcubed@27165 83 // to avoid false sharing due to parallel access by different threads.
dcubed@27165 84 // This is an advisory recommendation.
dcubed@27165 85 // - The general layout of the fields in ObjectMonitor is:
dcubed@27165 86 // _header
dcubed@27165 87 // <lightly_used_fields>
dcubed@27165 88 // <optional padding>
dcubed@27165 89 // _owner
dcubed@27165 90 // <remaining_fields>
dcubed@27165 91 // - The VM assumes write ordering and machine word alignment with
dcubed@27165 92 // respect to the _owner field and the <remaining_fields> that can
dcubed@27165 93 // be read in parallel by other threads.
dcubed@27165 94 // - Generally fields that are accessed closely together in time should
dcubed@27165 95 // be placed proximally in space to promote data cache locality. That
dcubed@27165 96 // is, temporal locality should condition spatial locality.
dcubed@27165 97 // - We have to balance avoiding false sharing with excessive invalidation
dcubed@27165 98 // from coherence traffic. As such, we try to cluster fields that tend
dcubed@27165 99 // to be _written_ at approximately the same time onto the same data
dcubed@27165 100 // cache line.
dcubed@27165 101 // - We also have to balance the natural tension between minimizing
dcubed@27165 102 // single threaded capacity misses with excessive multi-threaded
dcubed@27165 103 // coherency misses. There is no single optimal layout for both
dcubed@27165 104 // single-threaded and multi-threaded environments.
dcubed@27165 105 //
dcubed@27165 106 // - See ObjectMonitor::sanity_checks() for how critical restrictions are
dcubed@27165 107 // enforced and advisory recommendations are reported.
dcubed@27165 108 // - Adjacent ObjectMonitors should be separated by enough space to avoid
dcubed@27165 109 // false sharing. This is handled by the ObjectMonitor allocation code
dcubed@27165 110 // in synchronizer.cpp. Also see ObjectSynchronizer::sanity_checks().
dcubed@27165 111 //
dcubed@27165 112 // Futures notes:
dcubed@27165 113 // - Separating _owner from the <remaining_fields> by enough space to
dcubed@27165 114 // avoid false sharing might be profitable. Given
dcubed@27165 115 // http://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate
dcubed@27165 116 // we know that the CAS in monitorenter will invalidate the line
dcubed@27165 117 // underlying _owner. We want to avoid an L1 data cache miss on that
dcubed@27165 118 // same line for monitorexit. Putting these <remaining_fields>:
dcubed@27165 119 // _recursions, _EntryList, _cxq, and _succ, all of which may be
dcubed@27165 120 // fetched in the inflated unlock path, on a different cache line
dcubed@27165 121 // would make them immune to CAS-based invalidation from the _owner
dcubed@27165 122 // field.
dcubed@27165 123 //
dcubed@27165 124 // - The _recursions field should be of type int, or int32_t but not
dcubed@27165 125 // intptr_t. There's no reason to use a 64-bit type for this field
dcubed@27165 126 // in a 64-bit JVM.
duke@1 127
duke@1 128 class ObjectMonitor {
duke@1 129 public:
duke@1 130 enum {
duke@1 131 OM_OK, // no error
duke@1 132 OM_SYSTEM_ERROR, // operating system error
duke@1 133 OM_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException
duke@1 134 OM_INTERRUPTED, // Thread.interrupt()
duke@1 135 OM_TIMED_OUT // Object.wait() timed out
duke@1 136 };
duke@1 137
dcubed@27165 138 private:
dcubed@27165 139 friend class ObjectSynchronizer;
dcubed@27165 140 friend class ObjectWaiter;
dcubed@27165 141 friend class VMStructs;
dcubed@27165 142
dcubed@27165 143 volatile markOop _header; // displaced object header word - mark
dcubed@27165 144 void* volatile _object; // backward object pointer - strong root
duke@1 145 public:
dcubed@27165 146 ObjectMonitor * FreeNext; // Free list linkage
dcubed@27165 147 private:
dcubed@27165 148 DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE,
dcubed@27165 149 sizeof(volatile markOop) + sizeof(void * volatile) +
dcubed@27165 150 sizeof(ObjectMonitor *));
dcubed@27165 151 protected: // protected for JvmtiRawMonitor
dcubed@27165 152 void * volatile _owner; // pointer to owning thread OR BasicLock
dcubed@27165 153 volatile jlong _previous_owner_tid; // thread id of the previous owner of the monitor
dcubed@27165 154 volatile intptr_t _recursions; // recursion count, 0 for first entry
dcubed@27165 155 ObjectWaiter * volatile _EntryList; // Threads blocked on entry or reentry.
dcubed@27165 156 // The list is actually composed of WaitNodes,
dcubed@27165 157 // acting as proxies for Threads.
dcubed@27165 158 private:
dcubed@27165 159 ObjectWaiter * volatile _cxq; // LL of recently-arrived threads blocked on entry.
dcubed@27165 160 Thread * volatile _succ; // Heir presumptive thread - used for futile wakeup throttling
dcubed@27165 161 Thread * volatile _Responsible;
dcubed@27165 162
dcubed@27165 163 volatile int _Spinner; // for exit->spinner handoff optimization
dcubed@27165 164 volatile int _SpinDuration;
dcubed@27165 165
dcubed@27165 166 volatile jint _count; // reference count to prevent reclamation/deflation
dcubed@27165 167 // at stop-the-world time. See deflate_idle_monitors().
dcubed@27165 168 // _count is approximately |_WaitSet| + |_EntryList|
dcubed@27165 169 protected:
dcubed@27165 170 ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor
dcubed@27165 171 volatile jint _waiters; // number of waiting threads
dcubed@27165 172 private:
dcubed@27165 173 volatile int _WaitSetLock; // protects Wait Queue - simple spinlock
dcubed@27165 174
dcubed@27165 175 public:
dcubed@27165 176 static void Initialize();
dcubed@32614 177
dcubed@32614 178 // Only perform a PerfData operation if the PerfData object has been
dcubed@32614 179 // allocated and if the PerfDataManager has not freed the PerfData
dcubed@32614 180 // objects which can happen at normal VM shutdown.
dcubed@32614 181 //
dcubed@32614 182 #define OM_PERFDATA_OP(f, op_str) \
dcubed@32614 183 do { \
dcubed@32614 184 if (ObjectMonitor::_sync_ ## f != NULL && \
dcubed@32614 185 PerfDataManager::has_PerfData()) { \
dcubed@32614 186 ObjectMonitor::_sync_ ## f->op_str; \
dcubed@32614 187 } \
dcubed@32614 188 } while (0)
dcubed@32614 189
dcubed@27165 190 static PerfCounter * _sync_ContendedLockAttempts;
dcubed@27165 191 static PerfCounter * _sync_FutileWakeups;
dcubed@27165 192 static PerfCounter * _sync_Parks;
dcubed@27165 193 static PerfCounter * _sync_EmptyNotifications;
dcubed@27165 194 static PerfCounter * _sync_Notifications;
dcubed@27165 195 static PerfCounter * _sync_SlowEnter;
dcubed@27165 196 static PerfCounter * _sync_SlowExit;
dcubed@27165 197 static PerfCounter * _sync_SlowNotify;
dcubed@27165 198 static PerfCounter * _sync_SlowNotifyAll;
dcubed@27165 199 static PerfCounter * _sync_FailedSpins;
dcubed@27165 200 static PerfCounter * _sync_SuccessfulSpins;
dcubed@27165 201 static PerfCounter * _sync_PrivateA;
dcubed@27165 202 static PerfCounter * _sync_PrivateB;
dcubed@27165 203 static PerfCounter * _sync_MonInCirculation;
dcubed@27165 204 static PerfCounter * _sync_MonScavenged;
dcubed@27165 205 static PerfCounter * _sync_Inflations;
dcubed@27165 206 static PerfCounter * _sync_Deflations;
dcubed@27165 207 static PerfLongVariable * _sync_MonExtant;
dcubed@27165 208
dcubed@31782 209 static int Knob_ExitRelease;
dcubed@27165 210 static int Knob_Verbose;
dcubed@27165 211 static int Knob_VerifyInUse;
dcubed@31782 212 static int Knob_VerifyMatch;
dcubed@27165 213 static int Knob_SpinLimit;
dcubed@27165 214
dcubed@27165 215 void* operator new (size_t size) throw() {
dcubed@27165 216 return AllocateHeap(size, mtInternal);
dcubed@27165 217 }
dcubed@27165 218 void* operator new[] (size_t size) throw() {
dcubed@27165 219 return operator new (size);
dcubed@27165 220 }
dcubed@27165 221 void operator delete(void* p) {
coleenp@27880 222 FreeHeap(p);
dcubed@27165 223 }
dcubed@27165 224 void operator delete[] (void *p) {
dcubed@27165 225 operator delete(p);
dcubed@27165 226 }
dcubed@27165 227
duke@1 228 // TODO-FIXME: the "offset" routines should return a type of off_t instead of int ...
duke@1 229 // ByteSize would also be an appropriate type.
dcubed@26684 230 static int header_offset_in_bytes() { return offset_of(ObjectMonitor, _header); }
dcubed@26684 231 static int object_offset_in_bytes() { return offset_of(ObjectMonitor, _object); }
dcubed@26684 232 static int owner_offset_in_bytes() { return offset_of(ObjectMonitor, _owner); }
dcubed@26684 233 static int count_offset_in_bytes() { return offset_of(ObjectMonitor, _count); }
duke@1 234 static int recursions_offset_in_bytes() { return offset_of(ObjectMonitor, _recursions); }
dcubed@26684 235 static int cxq_offset_in_bytes() { return offset_of(ObjectMonitor, _cxq); }
dcubed@26684 236 static int succ_offset_in_bytes() { return offset_of(ObjectMonitor, _succ); }
dcubed@26684 237 static int EntryList_offset_in_bytes() { return offset_of(ObjectMonitor, _EntryList); }
duke@1 238
dcubed@27608 239 // ObjectMonitor references can be ORed with markOopDesc::monitor_value
dcubed@27608 240 // as part of the ObjectMonitor tagging mechanism. When we combine an
dcubed@27608 241 // ObjectMonitor reference with an offset, we need to remove the tag
dcubed@27608 242 // value in order to generate the proper address.
dcubed@27608 243 //
dcubed@27608 244 // We can either adjust the ObjectMonitor reference and then add the
dcubed@27608 245 // offset or we can adjust the offset that is added to the ObjectMonitor
dcubed@27608 246 // reference. The latter avoids an AGI (Address Generation Interlock)
dcubed@27608 247 // stall so the helper macro adjusts the offset value that is returned
dcubed@27608 248 // to the ObjectMonitor reference manipulation code:
dcubed@27608 249 //
dcubed@27608 250 #define OM_OFFSET_NO_MONITOR_VALUE_TAG(f) \
dcubed@27608 251 ((ObjectMonitor::f ## _offset_in_bytes()) - markOopDesc::monitor_value)
dcubed@27608 252
duke@1 253 markOop header() const;
duke@1 254 void set_header(markOop hdr);
duke@1 255
acorn@6975 256 intptr_t is_busy() const {
acorn@6975 257 // TODO-FIXME: merge _count and _waiters.
acorn@6975 258 // TODO-FIXME: assert _owner == null implies _recursions = 0
acorn@6975 259 // TODO-FIXME: assert _WaitSet != null implies _count > 0
dcubed@25064 260 return _count|_waiters|intptr_t(_owner)|intptr_t(_cxq)|intptr_t(_EntryList);
acorn@6975 261 }
acorn@6975 262
duke@1 263 intptr_t is_entered(Thread* current) const;
duke@1 264
duke@1 265 void* owner() const;
duke@1 266 void set_owner(void* owner);
duke@1 267
dcubed@27165 268 jint waiters() const;
duke@1 269
dcubed@27165 270 jint count() const;
dcubed@27165 271 void set_count(jint count);
dcubed@27165 272 jint contentions() const;
acorn@6975 273 intptr_t recursions() const { return _recursions; }
duke@1 274
dcubed@27165 275 // JVM/TI GetObjectMonitorUsage() needs this:
acorn@6975 276 ObjectWaiter* first_waiter() { return _WaitSet; }
acorn@6975 277 ObjectWaiter* next_waiter(ObjectWaiter* o) { return o->_next; }
acorn@6975 278 Thread* thread_of_waiter(ObjectWaiter* o) { return o->_thread; }
duke@1 279
dcubed@27165 280 protected:
dcubed@27165 281 // We don't typically expect or want the ctors or dtors to run.
dcubed@27165 282 // normal ObjectMonitors are type-stable and immortal.
dcubed@27165 283 ObjectMonitor() { ::memset((void *)this, 0, sizeof(*this)); }
acorn@6975 284
acorn@6975 285 ~ObjectMonitor() {
dcubed@26683 286 // TODO: Add asserts ...
dcubed@26683 287 // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0
dcubed@26683 288 // _count == 0 _EntryList == NULL etc
acorn@6975 289 }
acorn@6975 290
dcubed@26683 291 private:
dcubed@25064 292 void Recycle() {
acorn@6975 293 // TODO: add stronger asserts ...
acorn@6975 294 // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0
acorn@6975 295 // _count == 0 EntryList == NULL
acorn@6975 296 // _recursions == 0 _WaitSet == NULL
dcubed@27165 297 assert(((is_busy()|_recursions) == 0), "freeing inuse monitor");
dcubed@25064 298 _succ = NULL;
dcubed@25064 299 _EntryList = NULL;
dcubed@25064 300 _cxq = NULL;
dcubed@25064 301 _WaitSet = NULL;
dcubed@25064 302 _recursions = 0;
acorn@6975 303 }
acorn@6975 304
dcubed@26683 305 public:
duke@1 306
duke@1 307 void* object() const;
duke@1 308 void* object_addr();
duke@1 309 void set_object(void* obj);
duke@1 310
duke@1 311 bool check(TRAPS); // true if the thread owns the monitor.
duke@1 312 void check_slow(TRAPS);
duke@1 313 void clear();
dcubed@25633 314 static void sanity_checks(); // public for -XX:+ExecuteInternalVMTests
dcubed@25633 315 // in PRODUCT for -XX:SyncKnobs=Verbose=1
duke@1 316 #ifndef PRODUCT
duke@1 317 void verify();
duke@1 318 void print();
duke@1 319 #endif
duke@1 320
duke@1 321 void enter(TRAPS);
sla@18025 322 void exit(bool not_suspended, TRAPS);
duke@1 323 void wait(jlong millis, bool interruptable, TRAPS);
duke@1 324 void notify(TRAPS);
duke@1 325 void notifyAll(TRAPS);
duke@1 326
duke@1 327 // Use the following at your own risk
duke@1 328 intptr_t complete_exit(TRAPS);
duke@1 329 void reenter(intptr_t recursions, TRAPS);
duke@1 330
duke@1 331 private:
dcubed@25064 332 void AddWaiter(ObjectWaiter * waiter);
acorn@6975 333 static void DeferredInitialize();
dcubed@31856 334 void INotify(Thread * Self);
dcubed@25064 335 ObjectWaiter * DequeueWaiter();
dcubed@25064 336 void DequeueSpecificWaiter(ObjectWaiter * waiter);
dcubed@25064 337 void EnterI(TRAPS);
dcubed@25064 338 void ReenterI(Thread * Self, ObjectWaiter * SelfNode);
dcubed@25064 339 void UnlinkAfterAcquire(Thread * Self, ObjectWaiter * SelfNode);
dcubed@25064 340 int TryLock(Thread * Self);
dcubed@25064 341 int NotRunnable(Thread * Self, Thread * Owner);
dcubed@39702 342 int TrySpin(Thread * Self);
dcubed@25064 343 void ExitEpilog(Thread * Self, ObjectWaiter * Wakee);
dcubed@25064 344 bool ExitSuspendEquivalent(JavaThread * Self);
sla@18025 345 void post_monitor_wait_event(EventJavaMonitorWait * event,
dcubed@26683 346 jlong notifier_tid,
dcubed@26683 347 jlong timeout,
dcubed@26683 348 bool timedout);
duke@1 349
duke@1 350 };
acorn@6975 351
acorn@6975 352 #undef TEVENT
dcubed@26684 353 #define TEVENT(nom) { if (SyncVerbose) FEVENT(nom); }
acorn@6975 354
dcubed@31782 355 #define FEVENT(nom) \
dcubed@31782 356 { \
dcubed@31782 357 static volatile int ctr = 0; \
dcubed@31782 358 int v = ++ctr; \
dcubed@31782 359 if ((v & (v - 1)) == 0) { \
dcubed@31782 360 tty->print_cr("INFO: " #nom " : %d", v); \
dcubed@31782 361 tty->flush(); \
dcubed@31782 362 } \
dcubed@26684 363 }
acorn@6975 364
acorn@6975 365 #undef TEVENT
acorn@6975 366 #define TEVENT(nom) {;}
acorn@6975 367
stefank@7397 368
stefank@7397 369 #endif // SHARE_VM_RUNTIME_OBJECTMONITOR_HPP