46 #include "utilities/dtrace.hpp" |
46 #include "utilities/dtrace.hpp" |
47 #include "utilities/events.hpp" |
47 #include "utilities/events.hpp" |
48 #include "utilities/vmError.hpp" |
48 #include "utilities/vmError.hpp" |
49 #include "utilities/xmlstream.hpp" |
49 #include "utilities/xmlstream.hpp" |
50 |
50 |
51 // Dummy VM operation to act as first element in our circular double-linked list |
|
52 class VM_None: public VM_Operation { |
|
53 VMOp_Type type() const { return VMOp_None; } |
|
54 void doit() {}; |
|
55 }; |
|
56 |
|
57 VMOperationQueue::VMOperationQueue() { |
51 VMOperationQueue::VMOperationQueue() { |
58 // The queue is a circular doubled-linked list, which always contains |
52 // The queue is a circular doubled-linked list, which always contains |
59 // one element (i.e., one element means empty). |
53 // one element (i.e., one element means empty). |
60 for(int i = 0; i < nof_priorities; i++) { |
54 for(int i = 0; i < nof_priorities; i++) { |
61 _queue_length[i] = 0; |
55 _queue_length[i] = 0; |
62 _queue_counter = 0; |
56 _queue_counter = 0; |
63 _queue[i] = new VM_None(); |
57 _queue[i] = new VM_None("QueueHead"); |
64 _queue[i]->set_next(_queue[i]); |
58 _queue[i]->set_next(_queue[i]); |
65 _queue[i]->set_prev(_queue[i]); |
59 _queue[i]->set_prev(_queue[i]); |
66 } |
60 } |
67 _drain_list = NULL; |
61 _drain_list = NULL; |
68 } |
62 } |
227 } |
221 } |
228 |
222 |
229 //------------------------------------------------------------------------------------------------------------------ |
223 //------------------------------------------------------------------------------------------------------------------ |
230 // Implementation of VMThread stuff |
224 // Implementation of VMThread stuff |
231 |
225 |
232 bool VMThread::_should_terminate = false; |
226 bool VMThread::_should_terminate = false; |
233 bool VMThread::_terminated = false; |
227 bool VMThread::_terminated = false; |
234 Monitor* VMThread::_terminate_lock = NULL; |
228 Monitor* VMThread::_terminate_lock = NULL; |
235 VMThread* VMThread::_vm_thread = NULL; |
229 VMThread* VMThread::_vm_thread = NULL; |
236 VM_Operation* VMThread::_cur_vm_operation = NULL; |
230 VM_Operation* VMThread::_cur_vm_operation = NULL; |
237 VMOperationQueue* VMThread::_vm_queue = NULL; |
231 VMOperationQueue* VMThread::_vm_queue = NULL; |
238 PerfCounter* VMThread::_perf_accumulated_vm_operation_time = NULL; |
232 PerfCounter* VMThread::_perf_accumulated_vm_operation_time = NULL; |
239 const char* VMThread::_no_op_reason = NULL; |
233 uint64_t VMThread::_coalesced_count = 0; |
240 VMOperationTimeoutTask* VMThread::_timeout_task = NULL; |
234 VMOperationTimeoutTask* VMThread::_timeout_task = NULL; |
241 |
235 |
242 |
236 |
243 void VMThread::create() { |
237 void VMThread::create() { |
244 assert(vm_thread() == NULL, "we can only allocate one VMThread"); |
238 assert(vm_thread() == NULL, "we can only allocate one VMThread"); |
280 } |
274 } |
281 |
275 |
282 void VMThread::destroy() { |
276 void VMThread::destroy() { |
283 _vm_thread = NULL; // VM thread is gone |
277 _vm_thread = NULL; // VM thread is gone |
284 } |
278 } |
|
279 |
|
280 static VM_None halt_op("Halt"); |
285 |
281 |
286 void VMThread::run() { |
282 void VMThread::run() { |
287 assert(this == vm_thread(), "check"); |
283 assert(this == vm_thread(), "check"); |
288 |
284 |
289 // Notify_lock wait checks on active_handles() to rewait in |
285 // Notify_lock wait checks on active_handles() to rewait in |
318 xtty->end_elem(); |
314 xtty->end_elem(); |
319 assert(should_terminate(), "termination flag must be set"); |
315 assert(should_terminate(), "termination flag must be set"); |
320 } |
316 } |
321 |
317 |
322 // 4526887 let VM thread exit at Safepoint |
318 // 4526887 let VM thread exit at Safepoint |
323 _no_op_reason = "Halt"; |
319 _cur_vm_operation = &halt_op; |
324 SafepointSynchronize::begin(); |
320 SafepointSynchronize::begin(); |
325 |
321 |
326 if (VerifyBeforeExit) { |
322 if (VerifyBeforeExit) { |
327 HandleMark hm(VMThread::vm_thread()); |
323 HandleMark hm(VMThread::vm_thread()); |
328 // Among other things, this ensures that Eden top is correct. |
324 // Among other things, this ensures that Eden top is correct. |
433 if (c_heap_allocated) { |
429 if (c_heap_allocated) { |
434 delete _cur_vm_operation; |
430 delete _cur_vm_operation; |
435 } |
431 } |
436 } |
432 } |
437 |
433 |
438 bool VMThread::no_op_safepoint_needed(bool check_time) { |
434 static VM_None safepointALot_op("SafepointALot"); |
|
435 static VM_Cleanup cleanup_op; |
|
436 |
|
437 VM_Operation* VMThread::no_op_safepoint(bool check_time) { |
439 if (SafepointALot) { |
438 if (SafepointALot) { |
440 _no_op_reason = "SafepointALot"; |
439 return &safepointALot_op; |
441 return true; |
|
442 } |
440 } |
443 if (!SafepointSynchronize::is_cleanup_needed()) { |
441 if (!SafepointSynchronize::is_cleanup_needed()) { |
444 return false; |
442 return NULL; |
445 } |
443 } |
446 if (check_time) { |
444 if (check_time) { |
447 long interval = SafepointSynchronize::last_non_safepoint_interval(); |
445 long interval_ms = SafepointTracing::time_since_last_safepoint_ms(); |
448 bool max_time_exceeded = GuaranteedSafepointInterval != 0 && |
446 bool max_time_exceeded = GuaranteedSafepointInterval != 0 && |
449 (interval > GuaranteedSafepointInterval); |
447 (interval_ms > GuaranteedSafepointInterval); |
450 if (!max_time_exceeded) { |
448 if (!max_time_exceeded) { |
451 return false; |
449 return NULL; |
452 } |
450 } |
453 } |
451 } |
454 _no_op_reason = "Cleanup"; |
452 return &cleanup_op; |
455 return true; |
|
456 } |
453 } |
457 |
454 |
458 void VMThread::loop() { |
455 void VMThread::loop() { |
459 assert(_cur_vm_operation == NULL, "no current one should be executing"); |
456 assert(_cur_vm_operation == NULL, "no current one should be executing"); |
460 |
457 |
492 (os::elapsedTime() > (double)SelfDestructTimer * 60.0)) { |
489 (os::elapsedTime() > (double)SelfDestructTimer * 60.0)) { |
493 tty->print_cr("VM self-destructed"); |
490 tty->print_cr("VM self-destructed"); |
494 exit(-1); |
491 exit(-1); |
495 } |
492 } |
496 |
493 |
497 if (timedout && VMThread::no_op_safepoint_needed(false)) { |
494 if (timedout && (_cur_vm_operation = VMThread::no_op_safepoint(false)) != NULL) { |
498 MutexUnlockerEx mul(VMOperationQueue_lock, |
495 MutexUnlockerEx mul(VMOperationQueue_lock, |
499 Mutex::_no_safepoint_check_flag); |
496 Mutex::_no_safepoint_check_flag); |
500 // Force a safepoint since we have not had one for at least |
497 // Force a safepoint since we have not had one for at least |
501 // 'GuaranteedSafepointInterval' milliseconds. This will run all |
498 // 'GuaranteedSafepointInterval' milliseconds. This will run all |
502 // the clean-up processing that needs to be done regularly at a |
499 // the clean-up processing that needs to be done regularly at a |
504 SafepointSynchronize::begin(); |
501 SafepointSynchronize::begin(); |
505 #ifdef ASSERT |
502 #ifdef ASSERT |
506 if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot(); |
503 if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot(); |
507 #endif |
504 #endif |
508 SafepointSynchronize::end(); |
505 SafepointSynchronize::end(); |
|
506 _cur_vm_operation = NULL; |
509 } |
507 } |
510 _cur_vm_operation = _vm_queue->remove_next(); |
508 _cur_vm_operation = _vm_queue->remove_next(); |
511 |
509 |
512 // If we are at a safepoint we will evaluate all the operations that |
510 // If we are at a safepoint we will evaluate all the operations that |
513 // follow that also require a safepoint |
511 // follow that also require a safepoint |
553 // to grab the next op now |
551 // to grab the next op now |
554 VM_Operation* next = _cur_vm_operation->next(); |
552 VM_Operation* next = _cur_vm_operation->next(); |
555 _vm_queue->set_drain_list(next); |
553 _vm_queue->set_drain_list(next); |
556 evaluate_operation(_cur_vm_operation); |
554 evaluate_operation(_cur_vm_operation); |
557 _cur_vm_operation = next; |
555 _cur_vm_operation = next; |
558 if (log_is_enabled(Debug, safepoint, stats)) { |
556 _coalesced_count++; |
559 SafepointSynchronize::inc_vmop_coalesced_count(); |
|
560 } |
|
561 } while (_cur_vm_operation != NULL); |
557 } while (_cur_vm_operation != NULL); |
562 } |
558 } |
563 // There is a chance that a thread enqueued a safepoint op |
559 // There is a chance that a thread enqueued a safepoint op |
564 // since we released the op-queue lock and initiated the safepoint. |
560 // since we released the op-queue lock and initiated the safepoint. |
565 // So we drain the queue again if there is anything there, as an |
561 // So we drain the queue again if there is anything there, as an |
620 } |
616 } |
621 |
617 |
622 // |
618 // |
623 // We want to make sure that we get to a safepoint regularly. |
619 // We want to make sure that we get to a safepoint regularly. |
624 // |
620 // |
625 if (VMThread::no_op_safepoint_needed(true)) { |
621 if ((_cur_vm_operation = VMThread::no_op_safepoint(false)) != NULL) { |
626 HandleMark hm(VMThread::vm_thread()); |
622 HandleMark hm(VMThread::vm_thread()); |
627 SafepointSynchronize::begin(); |
623 SafepointSynchronize::begin(); |
628 SafepointSynchronize::end(); |
624 SafepointSynchronize::end(); |
|
625 _cur_vm_operation = NULL; |
629 } |
626 } |
630 } |
627 } |
631 } |
628 } |
632 |
629 |
633 // A SkipGCALot object is used to elide the usual effect of gc-a-lot |
630 // A SkipGCALot object is used to elide the usual effect of gc-a-lot |