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