26 #include "compiler/compileBroker.hpp" |
26 #include "compiler/compileBroker.hpp" |
27 #include "gc/shared/collectedHeap.hpp" |
27 #include "gc/shared/collectedHeap.hpp" |
28 #include "jfr/jfrEvents.hpp" |
28 #include "jfr/jfrEvents.hpp" |
29 #include "jfr/support/jfrThreadId.hpp" |
29 #include "jfr/support/jfrThreadId.hpp" |
30 #include "logging/log.hpp" |
30 #include "logging/log.hpp" |
|
31 #include "logging/logStream.hpp" |
31 #include "logging/logConfiguration.hpp" |
32 #include "logging/logConfiguration.hpp" |
32 #include "memory/resourceArea.hpp" |
33 #include "memory/resourceArea.hpp" |
33 #include "oops/method.hpp" |
34 #include "oops/method.hpp" |
34 #include "oops/oop.inline.hpp" |
35 #include "oops/oop.inline.hpp" |
35 #include "oops/verifyOopClosure.hpp" |
36 #include "oops/verifyOopClosure.hpp" |
195 queue_oops_do(i, f); |
196 queue_oops_do(i, f); |
196 } |
197 } |
197 drain_list_oops_do(f); |
198 drain_list_oops_do(f); |
198 } |
199 } |
199 |
200 |
|
201 //------------------------------------------------------------------------------------------------------------------ |
|
202 // Timeout machinery |
|
203 |
|
204 void VMOperationTimeoutTask::task() { |
|
205 assert(AbortVMOnVMOperationTimeout, "only if enabled"); |
|
206 if (is_armed()) { |
|
207 jlong delay = (os::javaTimeMillis() - _arm_time); |
|
208 if (delay > AbortVMOnVMOperationTimeoutDelay) { |
|
209 fatal("VM operation took too long: " SIZE_FORMAT " ms (timeout: " SIZE_FORMAT " ms)", |
|
210 delay, AbortVMOnVMOperationTimeoutDelay); |
|
211 } |
|
212 } |
|
213 } |
|
214 |
|
215 bool VMOperationTimeoutTask::is_armed() { |
|
216 return OrderAccess::load_acquire(&_armed) != 0; |
|
217 } |
|
218 |
|
219 void VMOperationTimeoutTask::arm() { |
|
220 _arm_time = os::javaTimeMillis(); |
|
221 OrderAccess::release_store_fence(&_armed, 1); |
|
222 } |
|
223 |
|
224 void VMOperationTimeoutTask::disarm() { |
|
225 OrderAccess::release_store_fence(&_armed, 0); |
|
226 } |
200 |
227 |
201 //------------------------------------------------------------------------------------------------------------------ |
228 //------------------------------------------------------------------------------------------------------------------ |
202 // Implementation of VMThread stuff |
229 // Implementation of VMThread stuff |
203 |
230 |
204 bool VMThread::_should_terminate = false; |
231 bool VMThread::_should_terminate = false; |
207 VMThread* VMThread::_vm_thread = NULL; |
234 VMThread* VMThread::_vm_thread = NULL; |
208 VM_Operation* VMThread::_cur_vm_operation = NULL; |
235 VM_Operation* VMThread::_cur_vm_operation = NULL; |
209 VMOperationQueue* VMThread::_vm_queue = NULL; |
236 VMOperationQueue* VMThread::_vm_queue = NULL; |
210 PerfCounter* VMThread::_perf_accumulated_vm_operation_time = NULL; |
237 PerfCounter* VMThread::_perf_accumulated_vm_operation_time = NULL; |
211 const char* VMThread::_no_op_reason = NULL; |
238 const char* VMThread::_no_op_reason = NULL; |
|
239 VMOperationTimeoutTask* VMThread::_timeout_task = NULL; |
212 |
240 |
213 |
241 |
214 void VMThread::create() { |
242 void VMThread::create() { |
215 assert(vm_thread() == NULL, "we can only allocate one VMThread"); |
243 assert(vm_thread() == NULL, "we can only allocate one VMThread"); |
216 _vm_thread = new VMThread(); |
244 _vm_thread = new VMThread(); |
|
245 |
|
246 if (AbortVMOnVMOperationTimeout) { |
|
247 // Make sure we call the timeout task frequently enough, but not too frequent. |
|
248 // Try to make the interval 10% of the timeout delay, so that we miss the timeout |
|
249 // by those 10% at max. Periodic task also expects it to fit min/max intervals. |
|
250 size_t interval = (size_t)AbortVMOnVMOperationTimeoutDelay / 10; |
|
251 interval = interval / PeriodicTask::interval_gran * PeriodicTask::interval_gran; |
|
252 interval = MAX2<size_t>(interval, PeriodicTask::min_interval); |
|
253 interval = MIN2<size_t>(interval, PeriodicTask::max_interval); |
|
254 |
|
255 _timeout_task = new VMOperationTimeoutTask(interval); |
|
256 _timeout_task->enroll(); |
|
257 } else { |
|
258 assert(_timeout_task == NULL, "sanity"); |
|
259 } |
217 |
260 |
218 // Create VM operation queue |
261 // Create VM operation queue |
219 _vm_queue = new VMOperationQueue(); |
262 _vm_queue = new VMOperationQueue(); |
220 guarantee(_vm_queue != NULL, "just checking"); |
263 guarantee(_vm_queue != NULL, "just checking"); |
221 |
264 |
490 log_debug(vmthread)("Evaluating safepoint VM operation: %s", _cur_vm_operation->name()); |
533 log_debug(vmthread)("Evaluating safepoint VM operation: %s", _cur_vm_operation->name()); |
491 |
534 |
492 _vm_queue->set_drain_list(safepoint_ops); // ensure ops can be scanned |
535 _vm_queue->set_drain_list(safepoint_ops); // ensure ops can be scanned |
493 |
536 |
494 SafepointSynchronize::begin(); |
537 SafepointSynchronize::begin(); |
|
538 |
|
539 if (_timeout_task != NULL) { |
|
540 _timeout_task->arm(); |
|
541 } |
|
542 |
495 evaluate_operation(_cur_vm_operation); |
543 evaluate_operation(_cur_vm_operation); |
496 // now process all queued safepoint ops, iteratively draining |
544 // now process all queued safepoint ops, iteratively draining |
497 // the queue until there are none left |
545 // the queue until there are none left |
498 do { |
546 do { |
499 _cur_vm_operation = safepoint_ops; |
547 _cur_vm_operation = safepoint_ops; |
531 } |
579 } |
532 } while(safepoint_ops != NULL); |
580 } while(safepoint_ops != NULL); |
533 |
581 |
534 _vm_queue->set_drain_list(NULL); |
582 _vm_queue->set_drain_list(NULL); |
535 |
583 |
|
584 if (_timeout_task != NULL) { |
|
585 _timeout_task->disarm(); |
|
586 } |
|
587 |
536 // Complete safepoint synchronization |
588 // Complete safepoint synchronization |
537 SafepointSynchronize::end(); |
589 SafepointSynchronize::end(); |
538 |
590 |
539 } else { // not a safepoint operation |
591 } else { // not a safepoint operation |
540 log_debug(vmthread)("Evaluating non-safepoint VM operation: %s", _cur_vm_operation->name()); |
592 log_debug(vmthread)("Evaluating non-safepoint VM operation: %s", _cur_vm_operation->name()); |