annotate src/share/vm/runtime/safepoint.hpp @ 1145:e018e6884bd8

6631166: CMS: better heuristics when combatting fragmentation Summary: Autonomic per-worker free block cache sizing, tunable coalition policies, fixes to per-size block statistics, retuned gain and bandwidth of some feedback loop filters to allow quicker reactivity to abrupt changes in ambient demand, and other heuristics to reduce fragmentation of the CMS old gen. Also tightened some assertions, including those related to locking. Reviewed-by: jmasa
author ysr
date Wed, 23 Dec 2009 09:23:54 -0800
parents a61af66fc99e
children 4b0f2f4918ed
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 1997-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 //
a61af66fc99e Initial load
duke
parents:
diff changeset
26 // Safepoint synchronization
a61af66fc99e Initial load
duke
parents:
diff changeset
27 ////
a61af66fc99e Initial load
duke
parents:
diff changeset
28 // The VMThread or CMS_thread uses the SafepointSynchronize::begin/end
a61af66fc99e Initial load
duke
parents:
diff changeset
29 // methods to enter/exit a safepoint region. The begin method will roll
a61af66fc99e Initial load
duke
parents:
diff changeset
30 // all JavaThreads forward to a safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
31 //
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // JavaThreads must use the ThreadSafepointState abstraction (defined in
a61af66fc99e Initial load
duke
parents:
diff changeset
33 // thread.hpp) to indicate that that they are at a safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
34 //
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // The Mutex/Condition variable and ObjectLocker classes calls the enter/
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // exit safepoint methods, when a thread is blocked/restarted. Hence, all mutex exter/
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // exit points *must* be at a safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
38
a61af66fc99e Initial load
duke
parents:
diff changeset
39
a61af66fc99e Initial load
duke
parents:
diff changeset
40 class ThreadSafepointState;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 class SnippetCache;
a61af66fc99e Initial load
duke
parents:
diff changeset
42 class nmethod;
a61af66fc99e Initial load
duke
parents:
diff changeset
43
a61af66fc99e Initial load
duke
parents:
diff changeset
44 //
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // Implements roll-forward to safepoint (safepoint synchronization)
a61af66fc99e Initial load
duke
parents:
diff changeset
46 //
a61af66fc99e Initial load
duke
parents:
diff changeset
47 class SafepointSynchronize : AllStatic {
a61af66fc99e Initial load
duke
parents:
diff changeset
48 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
49 enum SynchronizeState {
a61af66fc99e Initial load
duke
parents:
diff changeset
50 _not_synchronized = 0, // Threads not synchronized at a safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // Keep this value 0. See the coment in do_call_back()
a61af66fc99e Initial load
duke
parents:
diff changeset
52 _synchronizing = 1, // Synchronizing in progress
a61af66fc99e Initial load
duke
parents:
diff changeset
53 _synchronized = 2 // All Java threads are stopped at a safepoint. Only VM thread is running
a61af66fc99e Initial load
duke
parents:
diff changeset
54 };
a61af66fc99e Initial load
duke
parents:
diff changeset
55
a61af66fc99e Initial load
duke
parents:
diff changeset
56 enum SafepointingThread {
a61af66fc99e Initial load
duke
parents:
diff changeset
57 _null_thread = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
58 _vm_thread = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
59 _other_thread = 2
a61af66fc99e Initial load
duke
parents:
diff changeset
60 };
a61af66fc99e Initial load
duke
parents:
diff changeset
61
a61af66fc99e Initial load
duke
parents:
diff changeset
62 enum SafepointTimeoutReason {
a61af66fc99e Initial load
duke
parents:
diff changeset
63 _spinning_timeout = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
64 _blocking_timeout = 1
a61af66fc99e Initial load
duke
parents:
diff changeset
65 };
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 typedef struct {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 int _vmop_type; // type of VM operation triggers the safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
69 int _nof_total_threads; // total number of Java threads
a61af66fc99e Initial load
duke
parents:
diff changeset
70 int _nof_initial_running_threads; // total number of initially seen running threads
a61af66fc99e Initial load
duke
parents:
diff changeset
71 int _nof_threads_wait_to_block; // total number of threads waiting for to block
a61af66fc99e Initial load
duke
parents:
diff changeset
72 bool _page_armed; // true if polling page is armed, false otherwise
a61af66fc99e Initial load
duke
parents:
diff changeset
73 int _nof_threads_hit_page_trap; // total number of threads hitting the page trap
a61af66fc99e Initial load
duke
parents:
diff changeset
74 jlong _time_to_spin; // total time in millis spent in spinning
a61af66fc99e Initial load
duke
parents:
diff changeset
75 jlong _time_to_wait_to_block; // total time in millis spent in waiting for to block
a61af66fc99e Initial load
duke
parents:
diff changeset
76 jlong _time_to_sync; // total time in millis spent in getting to _synchronized
a61af66fc99e Initial load
duke
parents:
diff changeset
77 jlong _time_to_exec_vmop; // total time in millis spent in vm operation itself
a61af66fc99e Initial load
duke
parents:
diff changeset
78 jlong _time_elapsed_since_last_safepoint; // time elasped since last safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
79 } SafepointStats;
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
82 static volatile SynchronizeState _state; // Threads might read this flag directly, without acquireing the Threads_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
83 static volatile int _waiting_to_block; // No. of threads we are waiting for to block.
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // This counter is used for fast versions of jni_Get<Primitive>Field.
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // An even value means there is no ongoing safepoint operations.
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // The counter is incremented ONLY at the beginning and end of each
a61af66fc99e Initial load
duke
parents:
diff changeset
88 // safepoint. The fact that Threads_lock is held throughout each pair of
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // increments (at the beginning and end of each safepoint) guarantees
a61af66fc99e Initial load
duke
parents:
diff changeset
90 // race freedom.
a61af66fc99e Initial load
duke
parents:
diff changeset
91 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
92 static volatile int _safepoint_counter;
a61af66fc99e Initial load
duke
parents:
diff changeset
93 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
94
a61af66fc99e Initial load
duke
parents:
diff changeset
95 static jlong _last_safepoint; // Time of last safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97 // statistics
a61af66fc99e Initial load
duke
parents:
diff changeset
98 static SafepointStats* _safepoint_stats; // array of SafepointStats struct
a61af66fc99e Initial load
duke
parents:
diff changeset
99 static int _cur_stat_index; // current index to the above array
a61af66fc99e Initial load
duke
parents:
diff changeset
100 static julong _safepoint_reasons[]; // safepoint count for each VM op
a61af66fc99e Initial load
duke
parents:
diff changeset
101 static julong _coalesced_vmop_count;// coalesced vmop count
a61af66fc99e Initial load
duke
parents:
diff changeset
102 static jlong _max_sync_time; // maximum sync time in nanos
a61af66fc99e Initial load
duke
parents:
diff changeset
103
a61af66fc99e Initial load
duke
parents:
diff changeset
104 static void begin_statistics(int nof_threads, int nof_running);
a61af66fc99e Initial load
duke
parents:
diff changeset
105 static void update_statistics_on_spin_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
106 static void update_statistics_on_sync_end(jlong end_time);
a61af66fc99e Initial load
duke
parents:
diff changeset
107 static void end_statistics(jlong end_time);
a61af66fc99e Initial load
duke
parents:
diff changeset
108 static void print_statistics();
a61af66fc99e Initial load
duke
parents:
diff changeset
109 inline static void inc_page_trap_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
110 Atomic::inc(&_safepoint_stats[_cur_stat_index]._nof_threads_hit_page_trap);
a61af66fc99e Initial load
duke
parents:
diff changeset
111 }
a61af66fc99e Initial load
duke
parents:
diff changeset
112
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // For debug long safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
114 static void print_safepoint_timeout(SafepointTimeoutReason timeout_reason);
a61af66fc99e Initial load
duke
parents:
diff changeset
115
a61af66fc99e Initial load
duke
parents:
diff changeset
116 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
117
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // Main entry points
a61af66fc99e Initial load
duke
parents:
diff changeset
119
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // Roll all threads forward to safepoint. Must be called by the
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // VMThread or CMS_thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
122 static void begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
123 static void end(); // Start all suspended threads again...
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 static bool safepoint_safe(JavaThread *thread, JavaThreadState state);
a61af66fc99e Initial load
duke
parents:
diff changeset
126
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // Query
a61af66fc99e Initial load
duke
parents:
diff changeset
128 inline static bool is_at_safepoint() { return _state == _synchronized; }
a61af66fc99e Initial load
duke
parents:
diff changeset
129 inline static bool is_synchronizing() { return _state == _synchronizing; }
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 inline static bool do_call_back() {
a61af66fc99e Initial load
duke
parents:
diff changeset
132 return (_state != _not_synchronized);
a61af66fc99e Initial load
duke
parents:
diff changeset
133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
134
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // Called when a thread volantary blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
136 static void block(JavaThread *thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
137 static void signal_thread_at_safepoint() { _waiting_to_block--; }
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // Exception handling for page polling
a61af66fc99e Initial load
duke
parents:
diff changeset
140 static void handle_polling_page_exception(JavaThread *thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 // VM Thread interface for determining safepoint rate
a61af66fc99e Initial load
duke
parents:
diff changeset
143 static long last_non_safepoint_interval() { return os::javaTimeMillis() - _last_safepoint; }
a61af66fc99e Initial load
duke
parents:
diff changeset
144 static bool is_cleanup_needed();
a61af66fc99e Initial load
duke
parents:
diff changeset
145 static void do_cleanup_tasks();
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
148 static void print_state() PRODUCT_RETURN;
a61af66fc99e Initial load
duke
parents:
diff changeset
149 static void safepoint_msg(const char* format, ...) PRODUCT_RETURN;
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151 static void deferred_initialize_stat();
a61af66fc99e Initial load
duke
parents:
diff changeset
152 static void print_stat_on_exit();
a61af66fc99e Initial load
duke
parents:
diff changeset
153 inline static void inc_vmop_coalesced_count() { _coalesced_vmop_count++; }
a61af66fc99e Initial load
duke
parents:
diff changeset
154
a61af66fc99e Initial load
duke
parents:
diff changeset
155 static void set_is_at_safepoint() { _state = _synchronized; }
a61af66fc99e Initial load
duke
parents:
diff changeset
156 static void set_is_not_at_safepoint() { _state = _not_synchronized; }
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // assembly support
a61af66fc99e Initial load
duke
parents:
diff changeset
159 static address address_of_state() { return (address)&_state; }
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 static address safepoint_counter_addr() { return (address)&_safepoint_counter; }
a61af66fc99e Initial load
duke
parents:
diff changeset
162 };
a61af66fc99e Initial load
duke
parents:
diff changeset
163
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // State class for a thread suspended at a safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
165 class ThreadSafepointState: public CHeapObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
166 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // These states are maintained by VM thread while threads are being brought
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // to a safepoint. After SafepointSynchronize::end(), they are reset to
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // _running.
a61af66fc99e Initial load
duke
parents:
diff changeset
170 enum suspend_type {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 _running = 0, // Thread state not yet determined (i.e., not at a safepoint yet)
a61af66fc99e Initial load
duke
parents:
diff changeset
172 _at_safepoint = 1, // Thread at a safepoint (f.ex., when blocked on a lock)
a61af66fc99e Initial load
duke
parents:
diff changeset
173 _call_back = 2 // Keep executing and wait for callback (if thread is in interpreted or vm)
a61af66fc99e Initial load
duke
parents:
diff changeset
174 };
a61af66fc99e Initial load
duke
parents:
diff changeset
175 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
176 volatile bool _at_poll_safepoint; // At polling page safepoint (NOT a poll return safepoint)
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // Thread has called back the safepoint code (for debugging)
a61af66fc99e Initial load
duke
parents:
diff changeset
178 bool _has_called_back;
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180 JavaThread * _thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
181 volatile suspend_type _type;
a61af66fc99e Initial load
duke
parents:
diff changeset
182
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
185 ThreadSafepointState(JavaThread *thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
186
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // examine/roll-forward/restart
a61af66fc99e Initial load
duke
parents:
diff changeset
188 void examine_state_of_thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
189 void roll_forward(suspend_type type);
a61af66fc99e Initial load
duke
parents:
diff changeset
190 void restart();
a61af66fc99e Initial load
duke
parents:
diff changeset
191
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // Query
a61af66fc99e Initial load
duke
parents:
diff changeset
193 JavaThread* thread() const { return _thread; }
a61af66fc99e Initial load
duke
parents:
diff changeset
194 suspend_type type() const { return _type; }
a61af66fc99e Initial load
duke
parents:
diff changeset
195 bool is_running() const { return (_type==_running); }
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // Support for safepoint timeout (debugging)
a61af66fc99e Initial load
duke
parents:
diff changeset
198 bool has_called_back() const { return _has_called_back; }
a61af66fc99e Initial load
duke
parents:
diff changeset
199 void set_has_called_back(bool val) { _has_called_back = val; }
a61af66fc99e Initial load
duke
parents:
diff changeset
200 bool is_at_poll_safepoint() { return _at_poll_safepoint; }
a61af66fc99e Initial load
duke
parents:
diff changeset
201 void set_at_poll_safepoint(bool val) { _at_poll_safepoint = val; }
a61af66fc99e Initial load
duke
parents:
diff changeset
202
a61af66fc99e Initial load
duke
parents:
diff changeset
203 void handle_polling_page_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
206 void print_on(outputStream* st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
207 void print() const { print_on(tty); }
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 // Initialize
a61af66fc99e Initial load
duke
parents:
diff changeset
210 static void create(JavaThread *thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
211 static void destroy(JavaThread *thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
212
a61af66fc99e Initial load
duke
parents:
diff changeset
213 void safepoint_msg(const char* format, ...) {
a61af66fc99e Initial load
duke
parents:
diff changeset
214 if (ShowSafepointMsgs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
215 va_list ap;
a61af66fc99e Initial load
duke
parents:
diff changeset
216 va_start(ap, format);
a61af66fc99e Initial load
duke
parents:
diff changeset
217 tty->vprint_cr(format, ap);
a61af66fc99e Initial load
duke
parents:
diff changeset
218 va_end(ap);
a61af66fc99e Initial load
duke
parents:
diff changeset
219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
221 };
a61af66fc99e Initial load
duke
parents:
diff changeset
222
a61af66fc99e Initial load
duke
parents:
diff changeset
223 //
a61af66fc99e Initial load
duke
parents:
diff changeset
224 // CounterDecay
a61af66fc99e Initial load
duke
parents:
diff changeset
225 //
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // Interates through invocation counters and decrements them. This
a61af66fc99e Initial load
duke
parents:
diff changeset
227 // is done at each safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
228 //
a61af66fc99e Initial load
duke
parents:
diff changeset
229 class CounterDecay : public AllStatic {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 static jlong _last_timestamp;
a61af66fc99e Initial load
duke
parents:
diff changeset
231 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
232 static void decay();
a61af66fc99e Initial load
duke
parents:
diff changeset
233 static bool is_decay_needed() { return (os::javaTimeMillis() - _last_timestamp) > CounterDecayMinIntervalLength; }
a61af66fc99e Initial load
duke
parents:
diff changeset
234 };