src/share/vm/runtime/objectMonitor.hpp

Thu, 24 May 2018 18:41:44 +0800

author
aoqi
date
Thu, 24 May 2018 18:41:44 +0800
changeset 8856
ac27a9c85bea
parent 8729
402618d5afc9
parent 6876
710a3c8b516e
child 9931
fd44df5e3bc3
permissions
-rw-r--r--

Merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #ifndef SHARE_VM_RUNTIME_OBJECTMONITOR_HPP
aoqi@0 26 #define SHARE_VM_RUNTIME_OBJECTMONITOR_HPP
aoqi@0 27
aoqi@0 28 #include "runtime/os.hpp"
aoqi@0 29 #include "runtime/park.hpp"
aoqi@0 30 #include "runtime/perfData.hpp"
aoqi@0 31
aoqi@0 32 // ObjectWaiter serves as a "proxy" or surrogate thread.
aoqi@0 33 // TODO-FIXME: Eliminate ObjectWaiter and use the thread-specific
aoqi@0 34 // ParkEvent instead. Beware, however, that the JVMTI code
aoqi@0 35 // knows about ObjectWaiters, so we'll have to reconcile that code.
aoqi@0 36 // See next_waiter(), first_waiter(), etc.
aoqi@0 37
aoqi@0 38 class ObjectWaiter : public StackObj {
aoqi@0 39 public:
aoqi@0 40 enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ } ;
aoqi@0 41 enum Sorted { PREPEND, APPEND, SORTED } ;
aoqi@0 42 ObjectWaiter * volatile _next;
aoqi@0 43 ObjectWaiter * volatile _prev;
aoqi@0 44 Thread* _thread;
aoqi@0 45 jlong _notifier_tid;
aoqi@0 46 ParkEvent * _event;
aoqi@0 47 volatile int _notified ;
aoqi@0 48 volatile TStates TState ;
aoqi@0 49 Sorted _Sorted ; // List placement disposition
aoqi@0 50 bool _active ; // Contention monitoring is enabled
aoqi@0 51 public:
aoqi@0 52 ObjectWaiter(Thread* thread);
aoqi@0 53
aoqi@0 54 void wait_reenter_begin(ObjectMonitor *mon);
aoqi@0 55 void wait_reenter_end(ObjectMonitor *mon);
aoqi@0 56 };
aoqi@0 57
aoqi@0 58 // forward declaration to avoid include tracing.hpp
aoqi@0 59 class EventJavaMonitorWait;
aoqi@0 60
aoqi@0 61 // WARNING:
aoqi@0 62 // This is a very sensitive and fragile class. DO NOT make any
aoqi@0 63 // change unless you are fully aware of the underlying semantics.
aoqi@0 64
aoqi@0 65 // This class can not inherit from any other class, because I have
aoqi@0 66 // to let the displaced header be the very first word. Otherwise I
aoqi@0 67 // have to let markOop include this file, which would export the
aoqi@0 68 // monitor data structure to everywhere.
aoqi@0 69 //
aoqi@0 70 // The ObjectMonitor class is used to implement JavaMonitors which have
aoqi@0 71 // transformed from the lightweight structure of the thread stack to a
aoqi@0 72 // heavy weight lock due to contention
aoqi@0 73
aoqi@0 74 // It is also used as RawMonitor by the JVMTI
aoqi@0 75
aoqi@0 76
aoqi@0 77 class ObjectMonitor {
aoqi@0 78 public:
aoqi@0 79 enum {
aoqi@0 80 OM_OK, // no error
aoqi@0 81 OM_SYSTEM_ERROR, // operating system error
aoqi@0 82 OM_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException
aoqi@0 83 OM_INTERRUPTED, // Thread.interrupt()
aoqi@0 84 OM_TIMED_OUT // Object.wait() timed out
aoqi@0 85 };
aoqi@0 86
aoqi@0 87 public:
aoqi@0 88 // TODO-FIXME: the "offset" routines should return a type of off_t instead of int ...
aoqi@0 89 // ByteSize would also be an appropriate type.
aoqi@0 90 static int header_offset_in_bytes() { return offset_of(ObjectMonitor, _header); }
aoqi@0 91 static int object_offset_in_bytes() { return offset_of(ObjectMonitor, _object); }
aoqi@0 92 static int owner_offset_in_bytes() { return offset_of(ObjectMonitor, _owner); }
aoqi@0 93 static int count_offset_in_bytes() { return offset_of(ObjectMonitor, _count); }
aoqi@0 94 static int recursions_offset_in_bytes() { return offset_of(ObjectMonitor, _recursions); }
aoqi@0 95 static int cxq_offset_in_bytes() { return offset_of(ObjectMonitor, _cxq) ; }
aoqi@0 96 static int succ_offset_in_bytes() { return offset_of(ObjectMonitor, _succ) ; }
aoqi@0 97 static int EntryList_offset_in_bytes() { return offset_of(ObjectMonitor, _EntryList); }
aoqi@0 98 static int FreeNext_offset_in_bytes() { return offset_of(ObjectMonitor, FreeNext); }
aoqi@0 99 static int WaitSet_offset_in_bytes() { return offset_of(ObjectMonitor, _WaitSet) ; }
aoqi@0 100 static int Responsible_offset_in_bytes() { return offset_of(ObjectMonitor, _Responsible);}
aoqi@0 101 static int Spinner_offset_in_bytes() { return offset_of(ObjectMonitor, _Spinner); }
aoqi@0 102
aoqi@0 103 public:
aoqi@0 104 // Eventaully we'll make provisions for multiple callbacks, but
aoqi@0 105 // now one will suffice.
aoqi@0 106 static int (*SpinCallbackFunction)(intptr_t, int) ;
aoqi@0 107 static intptr_t SpinCallbackArgument ;
aoqi@0 108
aoqi@0 109
aoqi@0 110 public:
aoqi@0 111 markOop header() const;
aoqi@0 112 void set_header(markOop hdr);
aoqi@0 113
aoqi@0 114 intptr_t is_busy() const {
aoqi@0 115 // TODO-FIXME: merge _count and _waiters.
aoqi@0 116 // TODO-FIXME: assert _owner == null implies _recursions = 0
aoqi@0 117 // TODO-FIXME: assert _WaitSet != null implies _count > 0
aoqi@0 118 return _count|_waiters|intptr_t(_owner)|intptr_t(_cxq)|intptr_t(_EntryList ) ;
aoqi@0 119 }
aoqi@0 120
aoqi@0 121 intptr_t is_entered(Thread* current) const;
aoqi@0 122
aoqi@0 123 void* owner() const;
aoqi@0 124 void set_owner(void* owner);
aoqi@0 125
aoqi@0 126 intptr_t waiters() const;
aoqi@0 127
aoqi@0 128 intptr_t count() const;
aoqi@0 129 void set_count(intptr_t count);
aoqi@0 130 intptr_t contentions() const ;
aoqi@0 131 intptr_t recursions() const { return _recursions; }
aoqi@0 132
aoqi@0 133 // JVM/DI GetMonitorInfo() needs this
aoqi@0 134 ObjectWaiter* first_waiter() { return _WaitSet; }
aoqi@0 135 ObjectWaiter* next_waiter(ObjectWaiter* o) { return o->_next; }
aoqi@0 136 Thread* thread_of_waiter(ObjectWaiter* o) { return o->_thread; }
aoqi@0 137
aoqi@0 138 // initialize the monitor, exception the semaphore, all other fields
aoqi@0 139 // are simple integers or pointers
aoqi@0 140 ObjectMonitor() {
aoqi@0 141 _header = NULL;
aoqi@0 142 _count = 0;
aoqi@0 143 _waiters = 0,
aoqi@0 144 _recursions = 0;
aoqi@0 145 _object = NULL;
aoqi@0 146 _owner = NULL;
aoqi@0 147 _WaitSet = NULL;
aoqi@0 148 _WaitSetLock = 0 ;
aoqi@0 149 _Responsible = NULL ;
aoqi@0 150 _succ = NULL ;
aoqi@0 151 _cxq = NULL ;
aoqi@0 152 FreeNext = NULL ;
aoqi@0 153 _EntryList = NULL ;
aoqi@0 154 _SpinFreq = 0 ;
aoqi@0 155 _SpinClock = 0 ;
aoqi@0 156 OwnerIsThread = 0 ;
aoqi@0 157 _previous_owner_tid = 0;
aoqi@0 158 }
aoqi@0 159
aoqi@0 160 ~ObjectMonitor() {
aoqi@0 161 // TODO: Add asserts ...
aoqi@0 162 // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0
aoqi@0 163 // _count == 0 _EntryList == NULL etc
aoqi@0 164 }
aoqi@0 165
aoqi@0 166 private:
aoqi@0 167 void Recycle () {
aoqi@0 168 // TODO: add stronger asserts ...
aoqi@0 169 // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0
aoqi@0 170 // _count == 0 EntryList == NULL
aoqi@0 171 // _recursions == 0 _WaitSet == NULL
aoqi@0 172 // TODO: assert (is_busy()|_recursions) == 0
aoqi@0 173 _succ = NULL ;
aoqi@0 174 _EntryList = NULL ;
aoqi@0 175 _cxq = NULL ;
aoqi@0 176 _WaitSet = NULL ;
aoqi@0 177 _recursions = 0 ;
aoqi@0 178 _SpinFreq = 0 ;
aoqi@0 179 _SpinClock = 0 ;
aoqi@0 180 OwnerIsThread = 0 ;
aoqi@0 181 }
aoqi@0 182
aoqi@0 183 public:
aoqi@0 184
aoqi@0 185 void* object() const;
aoqi@0 186 void* object_addr();
aoqi@0 187 void set_object(void* obj);
aoqi@0 188
aoqi@0 189 bool check(TRAPS); // true if the thread owns the monitor.
aoqi@0 190 void check_slow(TRAPS);
aoqi@0 191 void clear();
kevinw@8729 192 static void sanity_checks(); // public for -XX:+ExecuteInternalVMTests
kevinw@8729 193 // in PRODUCT for -XX:SyncKnobs=Verbose=1
aoqi@0 194 #ifndef PRODUCT
aoqi@0 195 void verify();
aoqi@0 196 void print();
aoqi@0 197 #endif
aoqi@0 198
aoqi@0 199 bool try_enter (TRAPS) ;
aoqi@0 200 void enter(TRAPS);
aoqi@0 201 void exit(bool not_suspended, TRAPS);
aoqi@0 202 void wait(jlong millis, bool interruptable, TRAPS);
aoqi@0 203 void notify(TRAPS);
aoqi@0 204 void notifyAll(TRAPS);
aoqi@0 205
aoqi@0 206 // Use the following at your own risk
aoqi@0 207 intptr_t complete_exit(TRAPS);
aoqi@0 208 void reenter(intptr_t recursions, TRAPS);
aoqi@0 209
aoqi@0 210 private:
aoqi@0 211 void AddWaiter (ObjectWaiter * waiter) ;
aoqi@0 212 static void DeferredInitialize();
aoqi@0 213
aoqi@0 214 ObjectWaiter * DequeueWaiter () ;
aoqi@0 215 void DequeueSpecificWaiter (ObjectWaiter * waiter) ;
aoqi@0 216 void EnterI (TRAPS) ;
aoqi@0 217 void ReenterI (Thread * Self, ObjectWaiter * SelfNode) ;
aoqi@0 218 void UnlinkAfterAcquire (Thread * Self, ObjectWaiter * SelfNode) ;
aoqi@0 219 int TryLock (Thread * Self) ;
aoqi@0 220 int NotRunnable (Thread * Self, Thread * Owner) ;
aoqi@0 221 int TrySpin_Fixed (Thread * Self) ;
aoqi@0 222 int TrySpin_VaryFrequency (Thread * Self) ;
aoqi@0 223 int TrySpin_VaryDuration (Thread * Self) ;
aoqi@0 224 void ctAsserts () ;
aoqi@0 225 void ExitEpilog (Thread * Self, ObjectWaiter * Wakee) ;
aoqi@0 226 bool ExitSuspendEquivalent (JavaThread * Self) ;
aoqi@0 227 void post_monitor_wait_event(EventJavaMonitorWait * event,
aoqi@0 228 jlong notifier_tid,
aoqi@0 229 jlong timeout,
aoqi@0 230 bool timedout);
aoqi@0 231
aoqi@0 232 private:
aoqi@0 233 friend class ObjectSynchronizer;
aoqi@0 234 friend class ObjectWaiter;
aoqi@0 235 friend class VMStructs;
aoqi@0 236
aoqi@0 237 // WARNING: this must be the very first word of ObjectMonitor
aoqi@0 238 // This means this class can't use any virtual member functions.
aoqi@0 239
aoqi@0 240 volatile markOop _header; // displaced object header word - mark
aoqi@0 241 void* volatile _object; // backward object pointer - strong root
aoqi@0 242
aoqi@0 243 double SharingPad [1] ; // temp to reduce false sharing
aoqi@0 244
aoqi@0 245 // All the following fields must be machine word aligned
aoqi@0 246 // The VM assumes write ordering wrt these fields, which can be
aoqi@0 247 // read from other threads.
aoqi@0 248
aoqi@0 249 protected: // protected for jvmtiRawMonitor
aoqi@0 250 void * volatile _owner; // pointer to owning thread OR BasicLock
aoqi@0 251 volatile jlong _previous_owner_tid; // thread id of the previous owner of the monitor
aoqi@0 252 volatile intptr_t _recursions; // recursion count, 0 for first entry
aoqi@0 253 private:
aoqi@0 254 int OwnerIsThread ; // _owner is (Thread *) vs SP/BasicLock
aoqi@0 255 ObjectWaiter * volatile _cxq ; // LL of recently-arrived threads blocked on entry.
aoqi@0 256 // The list is actually composed of WaitNodes, acting
aoqi@0 257 // as proxies for Threads.
aoqi@0 258 protected:
aoqi@0 259 ObjectWaiter * volatile _EntryList ; // Threads blocked on entry or reentry.
aoqi@0 260 private:
aoqi@0 261 Thread * volatile _succ ; // Heir presumptive thread - used for futile wakeup throttling
aoqi@0 262 Thread * volatile _Responsible ;
aoqi@0 263 int _PromptDrain ; // rqst to drain cxq into EntryList ASAP
aoqi@0 264
aoqi@0 265 volatile int _Spinner ; // for exit->spinner handoff optimization
aoqi@0 266 volatile int _SpinFreq ; // Spin 1-out-of-N attempts: success rate
aoqi@0 267 volatile int _SpinClock ;
aoqi@0 268 volatile int _SpinDuration ;
aoqi@0 269 volatile intptr_t _SpinState ; // MCS/CLH list of spinners
aoqi@0 270
aoqi@0 271 // TODO-FIXME: _count, _waiters and _recursions should be of
aoqi@0 272 // type int, or int32_t but not intptr_t. There's no reason
aoqi@0 273 // to use 64-bit fields for these variables on a 64-bit JVM.
aoqi@0 274
aoqi@0 275 volatile intptr_t _count; // reference count to prevent reclaimation/deflation
aoqi@0 276 // at stop-the-world time. See deflate_idle_monitors().
aoqi@0 277 // _count is approximately |_WaitSet| + |_EntryList|
aoqi@0 278 protected:
aoqi@0 279 volatile intptr_t _waiters; // number of waiting threads
aoqi@0 280 private:
aoqi@0 281 protected:
aoqi@0 282 ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor
aoqi@0 283 private:
aoqi@0 284 volatile int _WaitSetLock; // protects Wait Queue - simple spinlock
aoqi@0 285
aoqi@0 286 public:
aoqi@0 287 int _QMix ; // Mixed prepend queue discipline
aoqi@0 288 ObjectMonitor * FreeNext ; // Free list linkage
aoqi@0 289 intptr_t StatA, StatsB ;
aoqi@0 290
aoqi@0 291 public:
aoqi@0 292 static void Initialize () ;
aoqi@0 293 static PerfCounter * _sync_ContendedLockAttempts ;
aoqi@0 294 static PerfCounter * _sync_FutileWakeups ;
aoqi@0 295 static PerfCounter * _sync_Parks ;
aoqi@0 296 static PerfCounter * _sync_EmptyNotifications ;
aoqi@0 297 static PerfCounter * _sync_Notifications ;
aoqi@0 298 static PerfCounter * _sync_SlowEnter ;
aoqi@0 299 static PerfCounter * _sync_SlowExit ;
aoqi@0 300 static PerfCounter * _sync_SlowNotify ;
aoqi@0 301 static PerfCounter * _sync_SlowNotifyAll ;
aoqi@0 302 static PerfCounter * _sync_FailedSpins ;
aoqi@0 303 static PerfCounter * _sync_SuccessfulSpins ;
aoqi@0 304 static PerfCounter * _sync_PrivateA ;
aoqi@0 305 static PerfCounter * _sync_PrivateB ;
aoqi@0 306 static PerfCounter * _sync_MonInCirculation ;
aoqi@0 307 static PerfCounter * _sync_MonScavenged ;
aoqi@0 308 static PerfCounter * _sync_Inflations ;
aoqi@0 309 static PerfCounter * _sync_Deflations ;
aoqi@0 310 static PerfLongVariable * _sync_MonExtant ;
aoqi@0 311
aoqi@0 312 public:
aoqi@0 313 static int Knob_Verbose;
aoqi@0 314 static int Knob_SpinLimit;
aoqi@0 315 void* operator new (size_t size) throw() {
aoqi@0 316 return AllocateHeap(size, mtInternal);
aoqi@0 317 }
aoqi@0 318 void* operator new[] (size_t size) throw() {
aoqi@0 319 return operator new (size);
aoqi@0 320 }
aoqi@0 321 void operator delete(void* p) {
aoqi@0 322 FreeHeap(p, mtInternal);
aoqi@0 323 }
aoqi@0 324 void operator delete[] (void *p) {
aoqi@0 325 operator delete(p);
aoqi@0 326 }
aoqi@0 327 };
aoqi@0 328
aoqi@0 329 #undef TEVENT
aoqi@0 330 #define TEVENT(nom) {if (SyncVerbose) FEVENT(nom); }
aoqi@0 331
aoqi@0 332 #define FEVENT(nom) { static volatile int ctr = 0 ; int v = ++ctr ; if ((v & (v-1)) == 0) { ::printf (#nom " : %d \n", v); ::fflush(stdout); }}
aoqi@0 333
aoqi@0 334 #undef TEVENT
aoqi@0 335 #define TEVENT(nom) {;}
aoqi@0 336
aoqi@0 337
aoqi@0 338 #endif // SHARE_VM_RUNTIME_OBJECTMONITOR_HPP

mercurial