annotate src/share/vm/runtime/objectMonitor.hpp @ 94:0834225a7916

6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction Summary: The option CMSInitiatingPermOccupancyFraction now controls perm triggering threshold. Even though the actual value of the threshold has not yet been changed, so there is no change in policy, we now have the infrastructure in place for dynamically deciding when to collect the perm gen, an issue that will be addressed in the near future. Reviewed-by: jmasa
author ysr
date Sun, 16 Mar 2008 21:57:25 -0700
parents a61af66fc99e
children c18cbe5936b8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2 * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 // WARNING:
a61af66fc99e Initial load
duke
parents:
diff changeset
26 // This is a very sensitive and fragile class. DO NOT make any
a61af66fc99e Initial load
duke
parents:
diff changeset
27 // change unless you are fully aware of the underlying semantics.
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 // This class can not inherit from any other class, because I have
a61af66fc99e Initial load
duke
parents:
diff changeset
30 // to let the displaced header be the very first word. Otherwise I
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // have to let markOop include this file, which would export the
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // monitor data structure to everywhere.
a61af66fc99e Initial load
duke
parents:
diff changeset
33 //
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // The ObjectMonitor class is used to implement JavaMonitors which have
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // transformed from the lightweight structure of the thread stack to a
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // heavy weight lock due to contention
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 // It is also used as RawMonitor by the JVMTI
a61af66fc99e Initial load
duke
parents:
diff changeset
39
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41 class ObjectWaiter;
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43 class ObjectMonitor {
a61af66fc99e Initial load
duke
parents:
diff changeset
44 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
45 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
46 OM_OK, // no error
a61af66fc99e Initial load
duke
parents:
diff changeset
47 OM_SYSTEM_ERROR, // operating system error
a61af66fc99e Initial load
duke
parents:
diff changeset
48 OM_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException
a61af66fc99e Initial load
duke
parents:
diff changeset
49 OM_INTERRUPTED, // Thread.interrupt()
a61af66fc99e Initial load
duke
parents:
diff changeset
50 OM_TIMED_OUT // Object.wait() timed out
a61af66fc99e Initial load
duke
parents:
diff changeset
51 };
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // TODO-FIXME: the "offset" routines should return a type of off_t instead of int ...
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // ByteSize would also be an appropriate type.
a61af66fc99e Initial load
duke
parents:
diff changeset
56 static int header_offset_in_bytes() { return offset_of(ObjectMonitor, _header); }
a61af66fc99e Initial load
duke
parents:
diff changeset
57 static int object_offset_in_bytes() { return offset_of(ObjectMonitor, _object); }
a61af66fc99e Initial load
duke
parents:
diff changeset
58 static int owner_offset_in_bytes() { return offset_of(ObjectMonitor, _owner); }
a61af66fc99e Initial load
duke
parents:
diff changeset
59 static int count_offset_in_bytes() { return offset_of(ObjectMonitor, _count); }
a61af66fc99e Initial load
duke
parents:
diff changeset
60 static int recursions_offset_in_bytes() { return offset_of(ObjectMonitor, _recursions); }
a61af66fc99e Initial load
duke
parents:
diff changeset
61 static int cxq_offset_in_bytes() { return offset_of(ObjectMonitor, _cxq) ; }
a61af66fc99e Initial load
duke
parents:
diff changeset
62 static int succ_offset_in_bytes() { return offset_of(ObjectMonitor, _succ) ; }
a61af66fc99e Initial load
duke
parents:
diff changeset
63 static int EntryList_offset_in_bytes() { return offset_of(ObjectMonitor, _EntryList); }
a61af66fc99e Initial load
duke
parents:
diff changeset
64 static int FreeNext_offset_in_bytes() { return offset_of(ObjectMonitor, FreeNext); }
a61af66fc99e Initial load
duke
parents:
diff changeset
65 static int WaitSet_offset_in_bytes() { return offset_of(ObjectMonitor, _WaitSet) ; }
a61af66fc99e Initial load
duke
parents:
diff changeset
66 static int Responsible_offset_in_bytes() { return offset_of(ObjectMonitor, _Responsible);}
a61af66fc99e Initial load
duke
parents:
diff changeset
67 static int Spinner_offset_in_bytes() { return offset_of(ObjectMonitor, _Spinner); }
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // Eventaully we'll make provisions for multiple callbacks, but
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // now one will suffice.
a61af66fc99e Initial load
duke
parents:
diff changeset
72 static int (*SpinCallbackFunction)(intptr_t, int) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
73 static intptr_t SpinCallbackArgument ;
a61af66fc99e Initial load
duke
parents:
diff changeset
74
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
77 ObjectMonitor();
a61af66fc99e Initial load
duke
parents:
diff changeset
78 ~ObjectMonitor();
a61af66fc99e Initial load
duke
parents:
diff changeset
79
a61af66fc99e Initial load
duke
parents:
diff changeset
80 markOop header() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
81 void set_header(markOop hdr);
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 intptr_t is_busy() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
84 intptr_t is_entered(Thread* current) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
85
a61af66fc99e Initial load
duke
parents:
diff changeset
86 void* owner() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
87 void set_owner(void* owner);
a61af66fc99e Initial load
duke
parents:
diff changeset
88
a61af66fc99e Initial load
duke
parents:
diff changeset
89 intptr_t waiters() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 intptr_t count() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
92 void set_count(intptr_t count);
a61af66fc99e Initial load
duke
parents:
diff changeset
93 intptr_t contentions() const ;
a61af66fc99e Initial load
duke
parents:
diff changeset
94
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // JVM/DI GetMonitorInfo() needs this
a61af66fc99e Initial load
duke
parents:
diff changeset
96 Thread * thread_of_waiter (ObjectWaiter *) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
97 ObjectWaiter * first_waiter () ;
a61af66fc99e Initial load
duke
parents:
diff changeset
98 ObjectWaiter * next_waiter(ObjectWaiter* o);
a61af66fc99e Initial load
duke
parents:
diff changeset
99
a61af66fc99e Initial load
duke
parents:
diff changeset
100 intptr_t recursions() const { return _recursions; }
a61af66fc99e Initial load
duke
parents:
diff changeset
101
a61af66fc99e Initial load
duke
parents:
diff changeset
102 void* object() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
103 void* object_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
104 void set_object(void* obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 bool check(TRAPS); // true if the thread owns the monitor.
a61af66fc99e Initial load
duke
parents:
diff changeset
107 void check_slow(TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
108 void clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
109 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
110 void verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
111 void print();
a61af66fc99e Initial load
duke
parents:
diff changeset
112 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
113
a61af66fc99e Initial load
duke
parents:
diff changeset
114 bool try_enter (TRAPS) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
115 void enter(TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
116 void exit(TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
117 void wait(jlong millis, bool interruptable, TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
118 void notify(TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
119 void notifyAll(TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
120
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // Use the following at your own risk
a61af66fc99e Initial load
duke
parents:
diff changeset
122 intptr_t complete_exit(TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
123 void reenter(intptr_t recursions, TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 int raw_enter(TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
126 int raw_exit(TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
127 int raw_wait(jlong millis, bool interruptable, TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
128 int raw_notify(TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
129 int raw_notifyAll(TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // JVMTI support -- remove ASAP
a61af66fc99e Initial load
duke
parents:
diff changeset
133 int SimpleEnter (Thread * Self) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
134 int SimpleExit (Thread * Self) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
135 int SimpleWait (Thread * Self, jlong millis) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
136 int SimpleNotify (Thread * Self, bool All) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
137
a61af66fc99e Initial load
duke
parents:
diff changeset
138 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
139 void Recycle () ;
a61af66fc99e Initial load
duke
parents:
diff changeset
140 void AddWaiter (ObjectWaiter * waiter) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 ObjectWaiter * DequeueWaiter () ;
a61af66fc99e Initial load
duke
parents:
diff changeset
143 void DequeueSpecificWaiter (ObjectWaiter * waiter) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
144 void EnterI (TRAPS) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
145 void ReenterI (Thread * Self, ObjectWaiter * SelfNode) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
146 void UnlinkAfterAcquire (Thread * Self, ObjectWaiter * SelfNode) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
147 int TryLock (Thread * Self) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 int NotRunnable (Thread * Self, Thread * Owner) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
149 int TrySpin_Fixed (Thread * Self) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
150 int TrySpin_VaryFrequency (Thread * Self) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
151 int TrySpin_VaryDuration (Thread * Self) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
152 void ctAsserts () ;
a61af66fc99e Initial load
duke
parents:
diff changeset
153 void ExitEpilog (Thread * Self, ObjectWaiter * Wakee) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
154 bool ExitSuspendEquivalent (JavaThread * Self) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
157 friend class ObjectSynchronizer;
a61af66fc99e Initial load
duke
parents:
diff changeset
158 friend class ObjectWaiter;
a61af66fc99e Initial load
duke
parents:
diff changeset
159 friend class VMStructs;
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // WARNING: this must be the very first word of ObjectMonitor
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // This means this class can't use any virtual member functions.
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // TODO-FIXME: assert that offsetof(_header) is 0 or get rid of the
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // implicit 0 offset in emitted code.
a61af66fc99e Initial load
duke
parents:
diff changeset
165
a61af66fc99e Initial load
duke
parents:
diff changeset
166 volatile markOop _header; // displaced object header word - mark
a61af66fc99e Initial load
duke
parents:
diff changeset
167 void* volatile _object; // backward object pointer - strong root
a61af66fc99e Initial load
duke
parents:
diff changeset
168
a61af66fc99e Initial load
duke
parents:
diff changeset
169 double SharingPad [1] ; // temp to reduce false sharing
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // All the following fields must be machine word aligned
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // The VM assumes write ordering wrt these fields, which can be
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // read from other threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175 void * volatile _owner; // pointer to owning thread OR BasicLock
a61af66fc99e Initial load
duke
parents:
diff changeset
176 volatile intptr_t _recursions; // recursion count, 0 for first entry
a61af66fc99e Initial load
duke
parents:
diff changeset
177 int OwnerIsThread ; // _owner is (Thread *) vs SP/BasicLock
a61af66fc99e Initial load
duke
parents:
diff changeset
178 ObjectWaiter * volatile _cxq ; // LL of recently-arrived threads blocked on entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // The list is actually composed of WaitNodes, acting
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // as proxies for Threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
181 ObjectWaiter * volatile _EntryList ; // Threads blocked on entry or reentry.
a61af66fc99e Initial load
duke
parents:
diff changeset
182 Thread * volatile _succ ; // Heir presumptive thread - used for futile wakeup throttling
a61af66fc99e Initial load
duke
parents:
diff changeset
183 Thread * volatile _Responsible ;
a61af66fc99e Initial load
duke
parents:
diff changeset
184 int _PromptDrain ; // rqst to drain cxq into EntryList ASAP
a61af66fc99e Initial load
duke
parents:
diff changeset
185
a61af66fc99e Initial load
duke
parents:
diff changeset
186 volatile int _Spinner ; // for exit->spinner handoff optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
187 volatile int _SpinFreq ; // Spin 1-out-of-N attempts: success rate
a61af66fc99e Initial load
duke
parents:
diff changeset
188 volatile int _SpinClock ;
a61af66fc99e Initial load
duke
parents:
diff changeset
189 volatile int _SpinDuration ;
a61af66fc99e Initial load
duke
parents:
diff changeset
190 volatile intptr_t _SpinState ; // MCS/CLH list of spinners
a61af66fc99e Initial load
duke
parents:
diff changeset
191
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // TODO-FIXME: _count, _waiters and _recursions should be of
a61af66fc99e Initial load
duke
parents:
diff changeset
193 // type int, or int32_t but not intptr_t. There's no reason
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // to use 64-bit fields for these variables on a 64-bit JVM.
a61af66fc99e Initial load
duke
parents:
diff changeset
195
a61af66fc99e Initial load
duke
parents:
diff changeset
196 volatile intptr_t _count; // reference count to prevent reclaimation/deflation
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // at stop-the-world time. See deflate_idle_monitors().
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // _count is approximately |_WaitSet| + |_EntryList|
a61af66fc99e Initial load
duke
parents:
diff changeset
199 volatile intptr_t _waiters; // number of waiting threads
a61af66fc99e Initial load
duke
parents:
diff changeset
200 ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor
a61af66fc99e Initial load
duke
parents:
diff changeset
201 volatile int _WaitSetLock; // protects Wait Queue - simple spinlock
a61af66fc99e Initial load
duke
parents:
diff changeset
202
a61af66fc99e Initial load
duke
parents:
diff changeset
203 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
204 int _QMix ; // Mixed prepend queue discipline
a61af66fc99e Initial load
duke
parents:
diff changeset
205 ObjectMonitor * FreeNext ; // Free list linkage
a61af66fc99e Initial load
duke
parents:
diff changeset
206 intptr_t StatA, StatsB ;
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 };