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 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "compiler/compileBroker.hpp"
27 #include "gc/shared/collectedHeap.hpp"
28 #include "jfr/jfrEvents.hpp"
29 #include "jfr/support/jfrThreadId.hpp"
30 #include "logging/log.hpp"
31 #include "logging/logConfiguration.hpp"
32 #include "memory/resourceArea.hpp"
33 #include "oops/method.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "oops/verifyOopClosure.hpp"
36 #include "runtime/interfaceSupport.inline.hpp"
37 #include "runtime/mutexLocker.hpp"
38 #include "runtime/os.hpp"
39 #include "runtime/safepoint.hpp"
40 #include "runtime/thread.inline.hpp"
41 #include "runtime/vmThread.hpp"
42 #include "runtime/vmOperations.hpp"
43 #include "services/runtimeService.hpp"
44 #include "utilities/dtrace.hpp"
45 #include "utilities/events.hpp"
46 #include "utilities/vmError.hpp"
47 #include "utilities/xmlstream.hpp"
48
49 // Dummy VM operation to act as first element in our circular double-linked list
50 class VM_None: public VM_Operation {
180 int high_prio, low_prio;
181 if (_queue_counter++ < 10) {
182 high_prio = SafepointPriority;
183 low_prio = MediumPriority;
184 } else {
185 _queue_counter = 0;
186 high_prio = MediumPriority;
187 low_prio = SafepointPriority;
188 }
189
190 return queue_remove_front(queue_empty(high_prio) ? low_prio : high_prio);
191 }
192
193 void VMOperationQueue::oops_do(OopClosure* f) {
194 for(int i = 0; i < nof_priorities; i++) {
195 queue_oops_do(i, f);
196 }
197 drain_list_oops_do(f);
198 }
199
200
201 //------------------------------------------------------------------------------------------------------------------
202 // Implementation of VMThread stuff
203
204 bool VMThread::_should_terminate = false;
205 bool VMThread::_terminated = false;
206 Monitor* VMThread::_terminate_lock = NULL;
207 VMThread* VMThread::_vm_thread = NULL;
208 VM_Operation* VMThread::_cur_vm_operation = NULL;
209 VMOperationQueue* VMThread::_vm_queue = NULL;
210 PerfCounter* VMThread::_perf_accumulated_vm_operation_time = NULL;
211 const char* VMThread::_no_op_reason = NULL;
212
213
214 void VMThread::create() {
215 assert(vm_thread() == NULL, "we can only allocate one VMThread");
216 _vm_thread = new VMThread();
217
218 // Create VM operation queue
219 _vm_queue = new VMOperationQueue();
220 guarantee(_vm_queue != NULL, "just checking");
221
222 _terminate_lock = new Monitor(Mutex::safepoint, "VMThread::_terminate_lock", true,
223 Monitor::_safepoint_check_never);
224
225 if (UsePerfData) {
226 // jvmstat performance counters
227 Thread* THREAD = Thread::current();
228 _perf_accumulated_vm_operation_time =
229 PerfDataManager::create_counter(SUN_THREADS, "vmOperationTime",
230 PerfData::U_Ticks, CHECK);
231 }
232 }
233
234 VMThread::VMThread() : NamedThread() {
235 set_name("VM Thread");
236 }
237
475
476 if (should_terminate()) break;
477 } // Release mu_queue_lock
478
479 //
480 // Execute VM operation
481 //
482 { HandleMark hm(VMThread::vm_thread());
483
484 EventMark em("Executing VM operation: %s", vm_operation()->name());
485 assert(_cur_vm_operation != NULL, "we should have found an operation to execute");
486
487 // If we are at a safepoint we will evaluate all the operations that
488 // follow that also require a safepoint
489 if (_cur_vm_operation->evaluate_at_safepoint()) {
490 log_debug(vmthread)("Evaluating safepoint VM operation: %s", _cur_vm_operation->name());
491
492 _vm_queue->set_drain_list(safepoint_ops); // ensure ops can be scanned
493
494 SafepointSynchronize::begin();
495 evaluate_operation(_cur_vm_operation);
496 // now process all queued safepoint ops, iteratively draining
497 // the queue until there are none left
498 do {
499 _cur_vm_operation = safepoint_ops;
500 if (_cur_vm_operation != NULL) {
501 do {
502 log_debug(vmthread)("Evaluating coalesced safepoint VM operation: %s", _cur_vm_operation->name());
503 // evaluate_operation deletes the op object so we have
504 // to grab the next op now
505 VM_Operation* next = _cur_vm_operation->next();
506 _vm_queue->set_drain_list(next);
507 evaluate_operation(_cur_vm_operation);
508 _cur_vm_operation = next;
509 if (log_is_enabled(Debug, safepoint, stats)) {
510 SafepointSynchronize::inc_vmop_coalesced_count();
511 }
512 } while (_cur_vm_operation != NULL);
513 }
514 // There is a chance that a thread enqueued a safepoint op
515 // since we released the op-queue lock and initiated the safepoint.
516 // So we drain the queue again if there is anything there, as an
517 // optimization to try and reduce the number of safepoints.
518 // As the safepoint synchronizes us with JavaThreads we will see
519 // any enqueue made by a JavaThread, but the peek will not
520 // necessarily detect a concurrent enqueue by a GC thread, but
521 // that simply means the op will wait for the next major cycle of the
522 // VMThread - just as it would if the GC thread lost the race for
523 // the lock.
524 if (_vm_queue->peek_at_safepoint_priority()) {
525 // must hold lock while draining queue
526 MutexLockerEx mu_queue(VMOperationQueue_lock,
527 Mutex::_no_safepoint_check_flag);
528 safepoint_ops = _vm_queue->drain_at_safepoint_priority();
529 } else {
530 safepoint_ops = NULL;
531 }
532 } while(safepoint_ops != NULL);
533
534 _vm_queue->set_drain_list(NULL);
535
536 // Complete safepoint synchronization
537 SafepointSynchronize::end();
538
539 } else { // not a safepoint operation
540 log_debug(vmthread)("Evaluating non-safepoint VM operation: %s", _cur_vm_operation->name());
541 if (TraceLongCompiles) {
542 elapsedTimer t;
543 t.start();
544 evaluate_operation(_cur_vm_operation);
545 t.stop();
546 double secs = t.seconds();
547 if (secs * 1e3 > LongCompileThreshold) {
548 // XXX - _cur_vm_operation should not be accessed after
549 // the completed count has been incremented; the waiting
550 // thread may have already freed this memory.
551 tty->print_cr("vm %s: %3.7f secs]", _cur_vm_operation->name(), secs);
552 }
553 } else {
554 evaluate_operation(_cur_vm_operation);
|
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 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "compiler/compileBroker.hpp"
27 #include "gc/shared/collectedHeap.hpp"
28 #include "jfr/jfrEvents.hpp"
29 #include "jfr/support/jfrThreadId.hpp"
30 #include "logging/log.hpp"
31 #include "logging/logStream.hpp"
32 #include "logging/logConfiguration.hpp"
33 #include "memory/resourceArea.hpp"
34 #include "oops/method.hpp"
35 #include "oops/oop.inline.hpp"
36 #include "oops/verifyOopClosure.hpp"
37 #include "runtime/interfaceSupport.inline.hpp"
38 #include "runtime/mutexLocker.hpp"
39 #include "runtime/os.hpp"
40 #include "runtime/safepoint.hpp"
41 #include "runtime/thread.inline.hpp"
42 #include "runtime/vmThread.hpp"
43 #include "runtime/vmOperations.hpp"
44 #include "services/runtimeService.hpp"
45 #include "utilities/dtrace.hpp"
46 #include "utilities/events.hpp"
47 #include "utilities/vmError.hpp"
48 #include "utilities/xmlstream.hpp"
49
50 // Dummy VM operation to act as first element in our circular double-linked list
51 class VM_None: public VM_Operation {
181 int high_prio, low_prio;
182 if (_queue_counter++ < 10) {
183 high_prio = SafepointPriority;
184 low_prio = MediumPriority;
185 } else {
186 _queue_counter = 0;
187 high_prio = MediumPriority;
188 low_prio = SafepointPriority;
189 }
190
191 return queue_remove_front(queue_empty(high_prio) ? low_prio : high_prio);
192 }
193
194 void VMOperationQueue::oops_do(OopClosure* f) {
195 for(int i = 0; i < nof_priorities; i++) {
196 queue_oops_do(i, f);
197 }
198 drain_list_oops_do(f);
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 }
227
228 //------------------------------------------------------------------------------------------------------------------
229 // Implementation of VMThread stuff
230
231 bool VMThread::_should_terminate = false;
232 bool VMThread::_terminated = false;
233 Monitor* VMThread::_terminate_lock = NULL;
234 VMThread* VMThread::_vm_thread = NULL;
235 VM_Operation* VMThread::_cur_vm_operation = NULL;
236 VMOperationQueue* VMThread::_vm_queue = NULL;
237 PerfCounter* VMThread::_perf_accumulated_vm_operation_time = NULL;
238 const char* VMThread::_no_op_reason = NULL;
239 VMOperationTimeoutTask* VMThread::_timeout_task = NULL;
240
241
242 void VMThread::create() {
243 assert(vm_thread() == NULL, "we can only allocate one 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 }
260
261 // Create VM operation queue
262 _vm_queue = new VMOperationQueue();
263 guarantee(_vm_queue != NULL, "just checking");
264
265 _terminate_lock = new Monitor(Mutex::safepoint, "VMThread::_terminate_lock", true,
266 Monitor::_safepoint_check_never);
267
268 if (UsePerfData) {
269 // jvmstat performance counters
270 Thread* THREAD = Thread::current();
271 _perf_accumulated_vm_operation_time =
272 PerfDataManager::create_counter(SUN_THREADS, "vmOperationTime",
273 PerfData::U_Ticks, CHECK);
274 }
275 }
276
277 VMThread::VMThread() : NamedThread() {
278 set_name("VM Thread");
279 }
280
518
519 if (should_terminate()) break;
520 } // Release mu_queue_lock
521
522 //
523 // Execute VM operation
524 //
525 { HandleMark hm(VMThread::vm_thread());
526
527 EventMark em("Executing VM operation: %s", vm_operation()->name());
528 assert(_cur_vm_operation != NULL, "we should have found an operation to execute");
529
530 // If we are at a safepoint we will evaluate all the operations that
531 // follow that also require a safepoint
532 if (_cur_vm_operation->evaluate_at_safepoint()) {
533 log_debug(vmthread)("Evaluating safepoint VM operation: %s", _cur_vm_operation->name());
534
535 _vm_queue->set_drain_list(safepoint_ops); // ensure ops can be scanned
536
537 SafepointSynchronize::begin();
538
539 if (_timeout_task != NULL) {
540 _timeout_task->arm();
541 }
542
543 evaluate_operation(_cur_vm_operation);
544 // now process all queued safepoint ops, iteratively draining
545 // the queue until there are none left
546 do {
547 _cur_vm_operation = safepoint_ops;
548 if (_cur_vm_operation != NULL) {
549 do {
550 log_debug(vmthread)("Evaluating coalesced safepoint VM operation: %s", _cur_vm_operation->name());
551 // evaluate_operation deletes the op object so we have
552 // to grab the next op now
553 VM_Operation* next = _cur_vm_operation->next();
554 _vm_queue->set_drain_list(next);
555 evaluate_operation(_cur_vm_operation);
556 _cur_vm_operation = next;
557 if (log_is_enabled(Debug, safepoint, stats)) {
558 SafepointSynchronize::inc_vmop_coalesced_count();
559 }
560 } while (_cur_vm_operation != NULL);
561 }
562 // There is a chance that a thread enqueued a safepoint op
563 // since we released the op-queue lock and initiated the safepoint.
564 // So we drain the queue again if there is anything there, as an
565 // optimization to try and reduce the number of safepoints.
566 // As the safepoint synchronizes us with JavaThreads we will see
567 // any enqueue made by a JavaThread, but the peek will not
568 // necessarily detect a concurrent enqueue by a GC thread, but
569 // that simply means the op will wait for the next major cycle of the
570 // VMThread - just as it would if the GC thread lost the race for
571 // the lock.
572 if (_vm_queue->peek_at_safepoint_priority()) {
573 // must hold lock while draining queue
574 MutexLockerEx mu_queue(VMOperationQueue_lock,
575 Mutex::_no_safepoint_check_flag);
576 safepoint_ops = _vm_queue->drain_at_safepoint_priority();
577 } else {
578 safepoint_ops = NULL;
579 }
580 } while(safepoint_ops != NULL);
581
582 _vm_queue->set_drain_list(NULL);
583
584 if (_timeout_task != NULL) {
585 _timeout_task->disarm();
586 }
587
588 // Complete safepoint synchronization
589 SafepointSynchronize::end();
590
591 } else { // not a safepoint operation
592 log_debug(vmthread)("Evaluating non-safepoint VM operation: %s", _cur_vm_operation->name());
593 if (TraceLongCompiles) {
594 elapsedTimer t;
595 t.start();
596 evaluate_operation(_cur_vm_operation);
597 t.stop();
598 double secs = t.seconds();
599 if (secs * 1e3 > LongCompileThreshold) {
600 // XXX - _cur_vm_operation should not be accessed after
601 // the completed count has been incremented; the waiting
602 // thread may have already freed this memory.
603 tty->print_cr("vm %s: %3.7f secs]", _cur_vm_operation->name(), secs);
604 }
605 } else {
606 evaluate_operation(_cur_vm_operation);
|