Mercurial > hg > graal-jvmci-8
annotate src/share/vm/runtime/vmThread.cpp @ 2368:dde920245681
6896099: Integrate CMS heap ergo with default heap sizing ergo
6627787: CMS: JVM refuses to start up with -Xms16m -Xmx16m
7000125: CMS: Anti-monotone young gen sizing with respect to maximum whole heap size specification
7027529: CMS: retire CMSUseOldDefaults flag
Summary: Simplify CMS heap sizing code, relying on ergonomic initial sizing consistent with other collectors for the most part, controlling only young gen sizing to rein in pause times. Make CMS young gen sizing default statically cpu-dependant. Remove inconsistencies wrt generation sizing and policy code, allowing for the fixing for 6627787 and 7000125. For 7027529, retire the flag CMSUseOldDefaults which had been introduced as a bridge from JDK 5 to JDK 6 a number of years ago.
Reviewed-by: brutisso, poonam
author | ysr |
---|---|
date | Wed, 16 Mar 2011 10:37:08 -0700 |
parents | f95d63e2154a |
children | 1f4413413144 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "compiler/compileBroker.hpp" | |
27 #include "gc_interface/collectedHeap.hpp" | |
28 #include "memory/resourceArea.hpp" | |
29 #include "oops/methodOop.hpp" | |
30 #include "oops/oop.inline.hpp" | |
31 #include "runtime/interfaceSupport.hpp" | |
32 #include "runtime/mutexLocker.hpp" | |
33 #include "runtime/os.hpp" | |
34 #include "runtime/vmThread.hpp" | |
35 #include "runtime/vm_operations.hpp" | |
36 #include "services/runtimeService.hpp" | |
37 #include "utilities/dtrace.hpp" | |
38 #include "utilities/events.hpp" | |
39 #include "utilities/xmlstream.hpp" | |
40 #ifdef TARGET_OS_FAMILY_linux | |
41 # include "thread_linux.inline.hpp" | |
42 #endif | |
43 #ifdef TARGET_OS_FAMILY_solaris | |
44 # include "thread_solaris.inline.hpp" | |
45 #endif | |
46 #ifdef TARGET_OS_FAMILY_windows | |
47 # include "thread_windows.inline.hpp" | |
48 #endif | |
0 | 49 |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1260
diff
changeset
|
50 HS_DTRACE_PROBE_DECL3(hotspot, vmops__request, char *, uintptr_t, int); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1260
diff
changeset
|
51 HS_DTRACE_PROBE_DECL3(hotspot, vmops__begin, char *, uintptr_t, int); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1260
diff
changeset
|
52 HS_DTRACE_PROBE_DECL3(hotspot, vmops__end, char *, uintptr_t, int); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1260
diff
changeset
|
53 |
0 | 54 // Dummy VM operation to act as first element in our circular double-linked list |
55 class VM_Dummy: public VM_Operation { | |
56 VMOp_Type type() const { return VMOp_Dummy; } | |
57 void doit() {}; | |
58 }; | |
59 | |
60 VMOperationQueue::VMOperationQueue() { | |
61 // The queue is a circular doubled-linked list, which always contains | |
62 // one element (i.e., one element means empty). | |
63 for(int i = 0; i < nof_priorities; i++) { | |
64 _queue_length[i] = 0; | |
65 _queue_counter = 0; | |
66 _queue[i] = new VM_Dummy(); | |
67 _queue[i]->set_next(_queue[i]); | |
68 _queue[i]->set_prev(_queue[i]); | |
69 } | |
70 _drain_list = NULL; | |
71 } | |
72 | |
73 | |
74 bool VMOperationQueue::queue_empty(int prio) { | |
75 // It is empty if there is exactly one element | |
76 bool empty = (_queue[prio] == _queue[prio]->next()); | |
77 assert( (_queue_length[prio] == 0 && empty) || | |
78 (_queue_length[prio] > 0 && !empty), "sanity check"); | |
79 return _queue_length[prio] == 0; | |
80 } | |
81 | |
82 // Inserts an element to the right of the q element | |
83 void VMOperationQueue::insert(VM_Operation* q, VM_Operation* n) { | |
84 assert(q->next()->prev() == q && q->prev()->next() == q, "sanity check"); | |
85 n->set_prev(q); | |
86 n->set_next(q->next()); | |
87 q->next()->set_prev(n); | |
88 q->set_next(n); | |
89 } | |
90 | |
91 void VMOperationQueue::queue_add_front(int prio, VM_Operation *op) { | |
92 _queue_length[prio]++; | |
93 insert(_queue[prio]->next(), op); | |
94 } | |
95 | |
96 void VMOperationQueue::queue_add_back(int prio, VM_Operation *op) { | |
97 _queue_length[prio]++; | |
98 insert(_queue[prio]->prev(), op); | |
99 } | |
100 | |
101 | |
102 void VMOperationQueue::unlink(VM_Operation* q) { | |
103 assert(q->next()->prev() == q && q->prev()->next() == q, "sanity check"); | |
104 q->prev()->set_next(q->next()); | |
105 q->next()->set_prev(q->prev()); | |
106 } | |
107 | |
108 VM_Operation* VMOperationQueue::queue_remove_front(int prio) { | |
109 if (queue_empty(prio)) return NULL; | |
110 assert(_queue_length[prio] >= 0, "sanity check"); | |
111 _queue_length[prio]--; | |
112 VM_Operation* r = _queue[prio]->next(); | |
113 assert(r != _queue[prio], "cannot remove base element"); | |
114 unlink(r); | |
115 return r; | |
116 } | |
117 | |
118 VM_Operation* VMOperationQueue::queue_drain(int prio) { | |
119 if (queue_empty(prio)) return NULL; | |
120 DEBUG_ONLY(int length = _queue_length[prio];); | |
121 assert(length >= 0, "sanity check"); | |
122 _queue_length[prio] = 0; | |
123 VM_Operation* r = _queue[prio]->next(); | |
124 assert(r != _queue[prio], "cannot remove base element"); | |
125 // remove links to base element from head and tail | |
126 r->set_prev(NULL); | |
127 _queue[prio]->prev()->set_next(NULL); | |
128 // restore queue to empty state | |
129 _queue[prio]->set_next(_queue[prio]); | |
130 _queue[prio]->set_prev(_queue[prio]); | |
1489
cff162798819
6888953: some calls to function-like macros are missing semicolons
jcoomes
parents:
1324
diff
changeset
|
131 assert(queue_empty(prio), "drain corrupted queue"); |
0 | 132 #ifdef DEBUG |
133 int len = 0; | |
134 VM_Operation* cur; | |
135 for(cur = r; cur != NULL; cur=cur->next()) len++; | |
136 assert(len == length, "drain lost some ops"); | |
137 #endif | |
138 return r; | |
139 } | |
140 | |
141 void VMOperationQueue::queue_oops_do(int queue, OopClosure* f) { | |
142 VM_Operation* cur = _queue[queue]; | |
143 cur = cur->next(); | |
144 while (cur != _queue[queue]) { | |
145 cur->oops_do(f); | |
146 cur = cur->next(); | |
147 } | |
148 } | |
149 | |
150 void VMOperationQueue::drain_list_oops_do(OopClosure* f) { | |
151 VM_Operation* cur = _drain_list; | |
152 while (cur != NULL) { | |
153 cur->oops_do(f); | |
154 cur = cur->next(); | |
155 } | |
156 } | |
157 | |
158 //----------------------------------------------------------------- | |
159 // High-level interface | |
160 bool VMOperationQueue::add(VM_Operation *op) { | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1260
diff
changeset
|
161 |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1260
diff
changeset
|
162 HS_DTRACE_PROBE3(hotspot, vmops__request, op->name(), strlen(op->name()), |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1260
diff
changeset
|
163 op->evaluation_mode()); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1260
diff
changeset
|
164 |
0 | 165 // Encapsulates VM queue policy. Currently, that |
166 // only involves putting them on the right list | |
167 if (op->evaluate_at_safepoint()) { | |
168 queue_add_back(SafepointPriority, op); | |
169 return true; | |
170 } | |
171 | |
172 queue_add_back(MediumPriority, op); | |
173 return true; | |
174 } | |
175 | |
176 VM_Operation* VMOperationQueue::remove_next() { | |
177 // Assuming VMOperation queue is two-level priority queue. If there are | |
178 // more than two priorities, we need a different scheduling algorithm. | |
179 assert(SafepointPriority == 0 && MediumPriority == 1 && nof_priorities == 2, | |
180 "current algorithm does not work"); | |
181 | |
182 // simple counter based scheduling to prevent starvation of lower priority | |
183 // queue. -- see 4390175 | |
184 int high_prio, low_prio; | |
185 if (_queue_counter++ < 10) { | |
186 high_prio = SafepointPriority; | |
187 low_prio = MediumPriority; | |
188 } else { | |
189 _queue_counter = 0; | |
190 high_prio = MediumPriority; | |
191 low_prio = SafepointPriority; | |
192 } | |
193 | |
194 return queue_remove_front(queue_empty(high_prio) ? low_prio : high_prio); | |
195 } | |
196 | |
197 void VMOperationQueue::oops_do(OopClosure* f) { | |
198 for(int i = 0; i < nof_priorities; i++) { | |
199 queue_oops_do(i, f); | |
200 } | |
201 drain_list_oops_do(f); | |
202 } | |
203 | |
204 | |
205 //------------------------------------------------------------------------------------------------------------------ | |
206 // Implementation of VMThread stuff | |
207 | |
208 bool VMThread::_should_terminate = false; | |
209 bool VMThread::_terminated = false; | |
210 Monitor* VMThread::_terminate_lock = NULL; | |
211 VMThread* VMThread::_vm_thread = NULL; | |
212 VM_Operation* VMThread::_cur_vm_operation = NULL; | |
213 VMOperationQueue* VMThread::_vm_queue = NULL; | |
214 PerfCounter* VMThread::_perf_accumulated_vm_operation_time = NULL; | |
215 | |
216 | |
217 void VMThread::create() { | |
218 assert(vm_thread() == NULL, "we can only allocate one VMThread"); | |
219 _vm_thread = new VMThread(); | |
220 | |
221 // Create VM operation queue | |
222 _vm_queue = new VMOperationQueue(); | |
223 guarantee(_vm_queue != NULL, "just checking"); | |
224 | |
225 _terminate_lock = new Monitor(Mutex::safepoint, "VMThread::_terminate_lock", true); | |
226 | |
227 if (UsePerfData) { | |
228 // jvmstat performance counters | |
229 Thread* THREAD = Thread::current(); | |
230 _perf_accumulated_vm_operation_time = | |
231 PerfDataManager::create_counter(SUN_THREADS, "vmOperationTime", | |
232 PerfData::U_Ticks, CHECK); | |
233 } | |
234 } | |
235 | |
236 | |
1119
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
989
diff
changeset
|
237 VMThread::VMThread() : NamedThread() { |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
989
diff
changeset
|
238 set_name("VM Thread"); |
0 | 239 } |
240 | |
241 void VMThread::destroy() { | |
242 if (_vm_thread != NULL) { | |
243 delete _vm_thread; | |
244 _vm_thread = NULL; // VM thread is gone | |
245 } | |
246 } | |
247 | |
248 void VMThread::run() { | |
249 assert(this == vm_thread(), "check"); | |
250 | |
251 this->initialize_thread_local_storage(); | |
252 this->record_stack_base_and_size(); | |
253 // Notify_lock wait checks on active_handles() to rewait in | |
254 // case of spurious wakeup, it should wait on the last | |
255 // value set prior to the notify | |
256 this->set_active_handles(JNIHandleBlock::allocate_block()); | |
257 | |
258 { | |
259 MutexLocker ml(Notify_lock); | |
260 Notify_lock->notify(); | |
261 } | |
262 // Notify_lock is destroyed by Threads::create_vm() | |
263 | |
264 int prio = (VMThreadPriority == -1) | |
265 ? os::java_to_os_priority[NearMaxPriority] | |
266 : VMThreadPriority; | |
267 // Note that I cannot call os::set_priority because it expects Java | |
268 // priorities and I am *explicitly* using OS priorities so that it's | |
269 // possible to set the VM thread priority higher than any Java thread. | |
270 os::set_native_priority( this, prio ); | |
271 | |
272 // Wait for VM_Operations until termination | |
273 this->loop(); | |
274 | |
275 // Note the intention to exit before safepointing. | |
276 // 6295565 This has the effect of waiting for any large tty | |
277 // outputs to finish. | |
278 if (xtty != NULL) { | |
279 ttyLocker ttyl; | |
280 xtty->begin_elem("destroy_vm"); | |
281 xtty->stamp(); | |
282 xtty->end_elem(); | |
283 assert(should_terminate(), "termination flag must be set"); | |
284 } | |
285 | |
286 // 4526887 let VM thread exit at Safepoint | |
287 SafepointSynchronize::begin(); | |
288 | |
289 if (VerifyBeforeExit) { | |
290 HandleMark hm(VMThread::vm_thread()); | |
291 // Among other things, this ensures that Eden top is correct. | |
292 Universe::heap()->prepare_for_verify(); | |
293 os::check_heap(); | |
294 Universe::verify(true, true); // Silent verification to not polute normal output | |
295 } | |
296 | |
297 CompileBroker::set_should_block(); | |
298 | |
299 // wait for threads (compiler threads or daemon threads) in the | |
300 // _thread_in_native state to block. | |
301 VM_Exit::wait_for_threads_in_native_to_block(); | |
302 | |
303 // signal other threads that VM process is gone | |
304 { | |
305 // Note: we must have the _no_safepoint_check_flag. Mutex::lock() allows | |
306 // VM thread to enter any lock at Safepoint as long as its _owner is NULL. | |
307 // If that happens after _terminate_lock->wait() has unset _owner | |
308 // but before it actually drops the lock and waits, the notification below | |
309 // may get lost and we will have a hang. To avoid this, we need to use | |
310 // Mutex::lock_without_safepoint_check(). | |
311 MutexLockerEx ml(_terminate_lock, Mutex::_no_safepoint_check_flag); | |
312 _terminated = true; | |
313 _terminate_lock->notify(); | |
314 } | |
315 | |
316 // Deletion must be done synchronously by the JNI DestroyJavaVM thread | |
317 // so that the VMThread deletion completes before the main thread frees | |
318 // up the CodeHeap. | |
319 | |
320 } | |
321 | |
322 | |
323 // Notify the VMThread that the last non-daemon JavaThread has terminated, | |
324 // and wait until operation is performed. | |
325 void VMThread::wait_for_vm_thread_exit() { | |
326 { MutexLocker mu(VMOperationQueue_lock); | |
327 _should_terminate = true; | |
328 VMOperationQueue_lock->notify(); | |
329 } | |
330 | |
331 // Note: VM thread leaves at Safepoint. We are not stopped by Safepoint | |
332 // because this thread has been removed from the threads list. But anything | |
333 // that could get blocked by Safepoint should not be used after this point, | |
334 // otherwise we will hang, since there is no one can end the safepoint. | |
335 | |
336 // Wait until VM thread is terminated | |
337 // Note: it should be OK to use Terminator_lock here. But this is called | |
338 // at a very delicate time (VM shutdown) and we are operating in non- VM | |
339 // thread at Safepoint. It's safer to not share lock with other threads. | |
340 { MutexLockerEx ml(_terminate_lock, Mutex::_no_safepoint_check_flag); | |
341 while(!VMThread::is_terminated()) { | |
342 _terminate_lock->wait(Mutex::_no_safepoint_check_flag); | |
343 } | |
344 } | |
345 } | |
346 | |
347 void VMThread::print_on(outputStream* st) const { | |
348 st->print("\"%s\" ", name()); | |
349 Thread::print_on(st); | |
350 st->cr(); | |
351 } | |
352 | |
353 void VMThread::evaluate_operation(VM_Operation* op) { | |
354 ResourceMark rm; | |
355 | |
356 { | |
357 PerfTraceTime vm_op_timer(perf_accumulated_vm_operation_time()); | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1260
diff
changeset
|
358 HS_DTRACE_PROBE3(hotspot, vmops__begin, op->name(), strlen(op->name()), |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1260
diff
changeset
|
359 op->evaluation_mode()); |
0 | 360 op->evaluate(); |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1260
diff
changeset
|
361 HS_DTRACE_PROBE3(hotspot, vmops__end, op->name(), strlen(op->name()), |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1260
diff
changeset
|
362 op->evaluation_mode()); |
0 | 363 } |
364 | |
365 // Last access of info in _cur_vm_operation! | |
366 bool c_heap_allocated = op->is_cheap_allocated(); | |
367 | |
368 // Mark as completed | |
369 if (!op->evaluate_concurrently()) { | |
370 op->calling_thread()->increment_vm_operation_completed_count(); | |
371 } | |
372 // It is unsafe to access the _cur_vm_operation after the 'increment_vm_operation_completed_count' call, | |
373 // since if it is stack allocated the calling thread might have deallocated | |
374 if (c_heap_allocated) { | |
375 delete _cur_vm_operation; | |
376 } | |
377 } | |
378 | |
379 | |
380 void VMThread::loop() { | |
381 assert(_cur_vm_operation == NULL, "no current one should be executing"); | |
382 | |
383 while(true) { | |
384 VM_Operation* safepoint_ops = NULL; | |
385 // | |
386 // Wait for VM operation | |
387 // | |
388 // use no_safepoint_check to get lock without attempting to "sneak" | |
389 { MutexLockerEx mu_queue(VMOperationQueue_lock, | |
390 Mutex::_no_safepoint_check_flag); | |
391 | |
392 // Look for new operation | |
393 assert(_cur_vm_operation == NULL, "no current one should be executing"); | |
394 _cur_vm_operation = _vm_queue->remove_next(); | |
395 | |
396 // Stall time tracking code | |
397 if (PrintVMQWaitTime && _cur_vm_operation != NULL && | |
398 !_cur_vm_operation->evaluate_concurrently()) { | |
399 long stall = os::javaTimeMillis() - _cur_vm_operation->timestamp(); | |
400 if (stall > 0) | |
401 tty->print_cr("%s stall: %Ld", _cur_vm_operation->name(), stall); | |
402 } | |
403 | |
404 while (!should_terminate() && _cur_vm_operation == NULL) { | |
405 // wait with a timeout to guarantee safepoints at regular intervals | |
406 bool timedout = | |
407 VMOperationQueue_lock->wait(Mutex::_no_safepoint_check_flag, | |
408 GuaranteedSafepointInterval); | |
409 | |
410 // Support for self destruction | |
411 if ((SelfDestructTimer != 0) && !is_error_reported() && | |
412 (os::elapsedTime() > SelfDestructTimer * 60)) { | |
413 tty->print_cr("VM self-destructed"); | |
414 exit(-1); | |
415 } | |
416 | |
417 if (timedout && (SafepointALot || | |
418 SafepointSynchronize::is_cleanup_needed())) { | |
419 MutexUnlockerEx mul(VMOperationQueue_lock, | |
420 Mutex::_no_safepoint_check_flag); | |
421 // Force a safepoint since we have not had one for at least | |
422 // 'GuaranteedSafepointInterval' milliseconds. This will run all | |
423 // the clean-up processing that needs to be done regularly at a | |
424 // safepoint | |
425 SafepointSynchronize::begin(); | |
426 #ifdef ASSERT | |
427 if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot(); | |
428 #endif | |
429 SafepointSynchronize::end(); | |
430 } | |
431 _cur_vm_operation = _vm_queue->remove_next(); | |
432 | |
433 // If we are at a safepoint we will evaluate all the operations that | |
434 // follow that also require a safepoint | |
435 if (_cur_vm_operation != NULL && | |
436 _cur_vm_operation->evaluate_at_safepoint()) { | |
437 safepoint_ops = _vm_queue->drain_at_safepoint_priority(); | |
438 } | |
439 } | |
440 | |
441 if (should_terminate()) break; | |
442 } // Release mu_queue_lock | |
443 | |
444 // | |
445 // Execute VM operation | |
446 // | |
447 { HandleMark hm(VMThread::vm_thread()); | |
448 | |
449 EventMark em("Executing VM operation: %s", vm_operation()->name()); | |
450 assert(_cur_vm_operation != NULL, "we should have found an operation to execute"); | |
451 | |
452 // Give the VM thread an extra quantum. Jobs tend to be bursty and this | |
453 // helps the VM thread to finish up the job. | |
454 // FIXME: When this is enabled and there are many threads, this can degrade | |
455 // performance significantly. | |
456 if( VMThreadHintNoPreempt ) | |
457 os::hint_no_preempt(); | |
458 | |
459 // If we are at a safepoint we will evaluate all the operations that | |
460 // follow that also require a safepoint | |
461 if (_cur_vm_operation->evaluate_at_safepoint()) { | |
462 | |
463 _vm_queue->set_drain_list(safepoint_ops); // ensure ops can be scanned | |
464 | |
465 SafepointSynchronize::begin(); | |
466 evaluate_operation(_cur_vm_operation); | |
467 // now process all queued safepoint ops, iteratively draining | |
468 // the queue until there are none left | |
469 do { | |
470 _cur_vm_operation = safepoint_ops; | |
471 if (_cur_vm_operation != NULL) { | |
472 do { | |
473 // evaluate_operation deletes the op object so we have | |
474 // to grab the next op now | |
475 VM_Operation* next = _cur_vm_operation->next(); | |
476 _vm_queue->set_drain_list(next); | |
477 evaluate_operation(_cur_vm_operation); | |
478 _cur_vm_operation = next; | |
479 if (PrintSafepointStatistics) { | |
480 SafepointSynchronize::inc_vmop_coalesced_count(); | |
481 } | |
482 } while (_cur_vm_operation != NULL); | |
483 } | |
484 // There is a chance that a thread enqueued a safepoint op | |
485 // since we released the op-queue lock and initiated the safepoint. | |
486 // So we drain the queue again if there is anything there, as an | |
487 // optimization to try and reduce the number of safepoints. | |
488 // As the safepoint synchronizes us with JavaThreads we will see | |
489 // any enqueue made by a JavaThread, but the peek will not | |
490 // necessarily detect a concurrent enqueue by a GC thread, but | |
491 // that simply means the op will wait for the next major cycle of the | |
492 // VMThread - just as it would if the GC thread lost the race for | |
493 // the lock. | |
494 if (_vm_queue->peek_at_safepoint_priority()) { | |
495 // must hold lock while draining queue | |
496 MutexLockerEx mu_queue(VMOperationQueue_lock, | |
497 Mutex::_no_safepoint_check_flag); | |
498 safepoint_ops = _vm_queue->drain_at_safepoint_priority(); | |
499 } else { | |
500 safepoint_ops = NULL; | |
501 } | |
502 } while(safepoint_ops != NULL); | |
503 | |
504 _vm_queue->set_drain_list(NULL); | |
505 | |
506 // Complete safepoint synchronization | |
507 SafepointSynchronize::end(); | |
508 | |
509 } else { // not a safepoint operation | |
510 if (TraceLongCompiles) { | |
511 elapsedTimer t; | |
512 t.start(); | |
513 evaluate_operation(_cur_vm_operation); | |
514 t.stop(); | |
515 double secs = t.seconds(); | |
516 if (secs * 1e3 > LongCompileThreshold) { | |
517 // XXX - _cur_vm_operation should not be accessed after | |
518 // the completed count has been incremented; the waiting | |
519 // thread may have already freed this memory. | |
520 tty->print_cr("vm %s: %3.7f secs]", _cur_vm_operation->name(), secs); | |
521 } | |
522 } else { | |
523 evaluate_operation(_cur_vm_operation); | |
524 } | |
525 | |
526 _cur_vm_operation = NULL; | |
527 } | |
528 } | |
529 | |
530 // | |
531 // Notify (potential) waiting Java thread(s) - lock without safepoint | |
532 // check so that sneaking is not possible | |
533 { MutexLockerEx mu(VMOperationRequest_lock, | |
534 Mutex::_no_safepoint_check_flag); | |
535 VMOperationRequest_lock->notify_all(); | |
536 } | |
537 | |
538 // | |
539 // We want to make sure that we get to a safepoint regularly. | |
540 // | |
541 if (SafepointALot || SafepointSynchronize::is_cleanup_needed()) { | |
542 long interval = SafepointSynchronize::last_non_safepoint_interval(); | |
543 bool max_time_exceeded = GuaranteedSafepointInterval != 0 && (interval > GuaranteedSafepointInterval); | |
544 if (SafepointALot || max_time_exceeded) { | |
545 HandleMark hm(VMThread::vm_thread()); | |
546 SafepointSynchronize::begin(); | |
547 SafepointSynchronize::end(); | |
548 } | |
549 } | |
550 } | |
551 } | |
552 | |
553 void VMThread::execute(VM_Operation* op) { | |
554 Thread* t = Thread::current(); | |
555 | |
556 if (!t->is_VM_thread()) { | |
806
821269eca479
6820167: GCALotAtAllSafepoints + FullGCALot(ScavengeALot) options crash JVM
ysr
parents:
0
diff
changeset
|
557 SkipGCALot sgcalot(t); // avoid re-entrant attempts to gc-a-lot |
0 | 558 // JavaThread or WatcherThread |
559 t->check_for_valid_safepoint_state(true); | |
560 | |
561 // New request from Java thread, evaluate prologue | |
562 if (!op->doit_prologue()) { | |
563 return; // op was cancelled | |
564 } | |
565 | |
566 // Setup VM_operations for execution | |
567 op->set_calling_thread(t, Thread::get_priority(t)); | |
568 | |
569 // It does not make sense to execute the epilogue, if the VM operation object is getting | |
570 // deallocated by the VM thread. | |
571 bool concurrent = op->evaluate_concurrently(); | |
572 bool execute_epilog = !op->is_cheap_allocated(); | |
573 assert(!concurrent || op->is_cheap_allocated(), "concurrent => cheap_allocated"); | |
574 | |
575 // Get ticket number for non-concurrent VM operations | |
576 int ticket = 0; | |
577 if (!concurrent) { | |
578 ticket = t->vm_operation_ticket(); | |
579 } | |
580 | |
581 // Add VM operation to list of waiting threads. We are guaranteed not to block while holding the | |
582 // VMOperationQueue_lock, so we can block without a safepoint check. This allows vm operation requests | |
583 // to be queued up during a safepoint synchronization. | |
584 { | |
585 VMOperationQueue_lock->lock_without_safepoint_check(); | |
586 bool ok = _vm_queue->add(op); | |
587 op->set_timestamp(os::javaTimeMillis()); | |
588 VMOperationQueue_lock->notify(); | |
589 VMOperationQueue_lock->unlock(); | |
590 // VM_Operation got skipped | |
591 if (!ok) { | |
592 assert(concurrent, "can only skip concurrent tasks"); | |
593 if (op->is_cheap_allocated()) delete op; | |
594 return; | |
595 } | |
596 } | |
597 | |
598 if (!concurrent) { | |
599 // Wait for completion of request (non-concurrent) | |
600 // Note: only a JavaThread triggers the safepoint check when locking | |
601 MutexLocker mu(VMOperationRequest_lock); | |
602 while(t->vm_operation_completed_count() < ticket) { | |
603 VMOperationRequest_lock->wait(!t->is_Java_thread()); | |
604 } | |
605 } | |
606 | |
607 if (execute_epilog) { | |
608 op->doit_epilogue(); | |
609 } | |
610 } else { | |
611 // invoked by VM thread; usually nested VM operation | |
612 assert(t->is_VM_thread(), "must be a VM thread"); | |
613 VM_Operation* prev_vm_operation = vm_operation(); | |
614 if (prev_vm_operation != NULL) { | |
615 // Check the VM operation allows nested VM operation. This normally not the case, e.g., the compiler | |
616 // does not allow nested scavenges or compiles. | |
617 if (!prev_vm_operation->allow_nested_vm_operations()) { | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1489
diff
changeset
|
618 fatal(err_msg("Nested VM operation %s requested by operation %s", |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1489
diff
changeset
|
619 op->name(), vm_operation()->name())); |
0 | 620 } |
621 op->set_calling_thread(prev_vm_operation->calling_thread(), prev_vm_operation->priority()); | |
622 } | |
623 | |
624 EventMark em("Executing %s VM operation: %s", prev_vm_operation ? "nested" : "", op->name()); | |
625 | |
626 // Release all internal handles after operation is evaluated | |
627 HandleMark hm(t); | |
628 _cur_vm_operation = op; | |
629 | |
630 if (op->evaluate_at_safepoint() && !SafepointSynchronize::is_at_safepoint()) { | |
631 SafepointSynchronize::begin(); | |
632 op->evaluate(); | |
633 SafepointSynchronize::end(); | |
634 } else { | |
635 op->evaluate(); | |
636 } | |
637 | |
638 // Free memory if needed | |
639 if (op->is_cheap_allocated()) delete op; | |
640 | |
641 _cur_vm_operation = prev_vm_operation; | |
642 } | |
643 } | |
644 | |
645 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
646 void VMThread::oops_do(OopClosure* f, CodeBlobClosure* cf) { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
647 Thread::oops_do(f, cf); |
0 | 648 _vm_queue->oops_do(f); |
649 } | |
650 | |
651 //------------------------------------------------------------------------------------------------------------------ | |
652 #ifndef PRODUCT | |
653 | |
654 void VMOperationQueue::verify_queue(int prio) { | |
655 // Check that list is correctly linked | |
656 int length = _queue_length[prio]; | |
657 VM_Operation *cur = _queue[prio]; | |
658 int i; | |
659 | |
660 // Check forward links | |
661 for(i = 0; i < length; i++) { | |
662 cur = cur->next(); | |
663 assert(cur != _queue[prio], "list to short (forward)"); | |
664 } | |
665 assert(cur->next() == _queue[prio], "list to long (forward)"); | |
666 | |
667 // Check backwards links | |
668 cur = _queue[prio]; | |
669 for(i = 0; i < length; i++) { | |
670 cur = cur->prev(); | |
671 assert(cur != _queue[prio], "list to short (backwards)"); | |
672 } | |
673 assert(cur->prev() == _queue[prio], "list to long (backwards)"); | |
674 } | |
675 | |
676 #endif | |
677 | |
678 void VMThread::verify() { | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
679 oops_do(&VerifyOopClosure::verify_oop, NULL); |
0 | 680 } |