147 } |
147 } |
148 } |
148 } |
149 |
149 |
150 //----------------------------------------------------------------- |
150 //----------------------------------------------------------------- |
151 // High-level interface |
151 // High-level interface |
152 bool VMOperationQueue::add(VM_Operation *op) { |
152 void VMOperationQueue::add(VM_Operation *op) { |
153 |
153 |
154 HOTSPOT_VMOPS_REQUEST( |
154 HOTSPOT_VMOPS_REQUEST( |
155 (char *) op->name(), strlen(op->name()), |
155 (char *) op->name(), strlen(op->name()), |
156 op->evaluation_mode()); |
156 op->evaluation_mode()); |
157 |
157 |
158 // Encapsulates VM queue policy. Currently, that |
158 // Encapsulates VM queue policy. Currently, that |
159 // only involves putting them on the right list |
159 // only involves putting them on the right list |
160 if (op->evaluate_at_safepoint()) { |
160 queue_add_back(op->evaluate_at_safepoint() ? SafepointPriority : MediumPriority, op); |
161 queue_add_back(SafepointPriority, op); |
|
162 return true; |
|
163 } |
|
164 |
|
165 queue_add_back(MediumPriority, op); |
|
166 return true; |
|
167 } |
161 } |
168 |
162 |
169 VM_Operation* VMOperationQueue::remove_next() { |
163 VM_Operation* VMOperationQueue::remove_next() { |
170 // Assuming VMOperation queue is two-level priority queue. If there are |
164 // Assuming VMOperation queue is two-level priority queue. If there are |
171 // more than two priorities, we need a different scheduling algorithm. |
165 // more than two priorities, we need a different scheduling algorithm. |
358 // Notify the VMThread that the last non-daemon JavaThread has terminated, |
352 // Notify the VMThread that the last non-daemon JavaThread has terminated, |
359 // and wait until operation is performed. |
353 // and wait until operation is performed. |
360 void VMThread::wait_for_vm_thread_exit() { |
354 void VMThread::wait_for_vm_thread_exit() { |
361 assert(Thread::current()->is_Java_thread(), "Should be a JavaThread"); |
355 assert(Thread::current()->is_Java_thread(), "Should be a JavaThread"); |
362 assert(((JavaThread*)Thread::current())->is_terminated(), "Should be terminated"); |
356 assert(((JavaThread*)Thread::current())->is_terminated(), "Should be terminated"); |
363 { MutexLocker mu(VMOperationQueue_lock, Mutex::_no_safepoint_check_flag); |
357 { MonitorLocker mu(VMOperationQueue_lock, Mutex::_no_safepoint_check_flag); |
364 _should_terminate = true; |
358 _should_terminate = true; |
365 VMOperationQueue_lock->notify(); |
359 mu.notify(); |
366 } |
360 } |
367 |
361 |
368 // Note: VM thread leaves at Safepoint. We are not stopped by Safepoint |
362 // Note: VM thread leaves at Safepoint. We are not stopped by Safepoint |
369 // because this thread has been removed from the threads list. But anything |
363 // because this thread has been removed from the threads list. But anything |
370 // that could get blocked by Safepoint should not be used after this point, |
364 // that could get blocked by Safepoint should not be used after this point, |
392 event->set_blocking(!is_concurrent); |
386 event->set_blocking(!is_concurrent); |
393 // Only write caller thread information for non-concurrent vm operations. |
387 // Only write caller thread information for non-concurrent vm operations. |
394 // For concurrent vm operations, the thread id is set to 0 indicating thread is unknown. |
388 // For concurrent vm operations, the thread id is set to 0 indicating thread is unknown. |
395 // This is because the caller thread could have exited already. |
389 // This is because the caller thread could have exited already. |
396 event->set_caller(is_concurrent ? 0 : JFR_THREAD_ID(op->calling_thread())); |
390 event->set_caller(is_concurrent ? 0 : JFR_THREAD_ID(op->calling_thread())); |
397 event->set_safepointId(evaluate_at_safepoint ? SafepointSynchronize::safepoint_counter() : 0); |
391 event->set_safepointId(evaluate_at_safepoint ? SafepointSynchronize::safepoint_id() : 0); |
398 event->commit(); |
392 event->commit(); |
399 } |
393 } |
400 |
394 |
401 void VMThread::evaluate_operation(VM_Operation* op) { |
395 void VMThread::evaluate_operation(VM_Operation* op) { |
402 ResourceMark rm; |
396 ResourceMark rm; |
560 // the queue until there are none left |
554 // the queue until there are none left |
561 do { |
555 do { |
562 _cur_vm_operation = safepoint_ops; |
556 _cur_vm_operation = safepoint_ops; |
563 if (_cur_vm_operation != NULL) { |
557 if (_cur_vm_operation != NULL) { |
564 do { |
558 do { |
|
559 EventMark em("Executing coalesced safepoint VM operation: %s", _cur_vm_operation->name()); |
565 log_debug(vmthread)("Evaluating coalesced safepoint VM operation: %s", _cur_vm_operation->name()); |
560 log_debug(vmthread)("Evaluating coalesced safepoint VM operation: %s", _cur_vm_operation->name()); |
566 // evaluate_operation deletes the op object so we have |
561 // evaluate_operation deletes the op object so we have |
567 // to grab the next op now |
562 // to grab the next op now |
568 VM_Operation* next = _cur_vm_operation->next(); |
563 VM_Operation* next = _cur_vm_operation->next(); |
569 _vm_queue->set_drain_list(next); |
564 _vm_queue->set_drain_list(next); |
623 } |
618 } |
624 } |
619 } |
625 |
620 |
626 // |
621 // |
627 // Notify (potential) waiting Java thread(s) |
622 // Notify (potential) waiting Java thread(s) |
628 { MutexLocker mu(VMOperationRequest_lock, Mutex::_no_safepoint_check_flag); |
623 { MonitorLocker mu(VMOperationRequest_lock, Mutex::_no_safepoint_check_flag); |
629 VMOperationRequest_lock->notify_all(); |
624 mu.notify_all(); |
630 } |
625 } |
631 |
626 |
632 // We want to make sure that we get to a safepoint regularly |
627 // We want to make sure that we get to a safepoint regularly |
633 // even when executing VMops that don't require safepoints. |
628 // even when executing VMops that don't require safepoints. |
634 if ((_cur_vm_operation = VMThread::no_op_safepoint()) != NULL) { |
629 if ((_cur_vm_operation = VMThread::no_op_safepoint()) != NULL) { |
672 SkipGCALot sgcalot(t); // avoid re-entrant attempts to gc-a-lot |
667 SkipGCALot sgcalot(t); // avoid re-entrant attempts to gc-a-lot |
673 // JavaThread or WatcherThread |
668 // JavaThread or WatcherThread |
674 bool concurrent = op->evaluate_concurrently(); |
669 bool concurrent = op->evaluate_concurrently(); |
675 // only blocking VM operations need to verify the caller's safepoint state: |
670 // only blocking VM operations need to verify the caller's safepoint state: |
676 if (!concurrent) { |
671 if (!concurrent) { |
677 t->check_for_valid_safepoint_state(true); |
672 t->check_for_valid_safepoint_state(); |
678 } |
673 } |
679 |
674 |
680 // New request from Java thread, evaluate prologue |
675 // New request from Java thread, evaluate prologue |
681 if (!op->doit_prologue()) { |
676 if (!op->doit_prologue()) { |
682 return; // op was cancelled |
677 return; // op was cancelled |
683 } |
678 } |
684 |
679 |
685 // Setup VM_operations for execution |
680 // Setup VM_operations for execution |
686 op->set_calling_thread(t, Thread::get_priority(t)); |
681 op->set_calling_thread(t); |
687 |
682 |
688 // It does not make sense to execute the epilogue, if the VM operation object is getting |
683 // It does not make sense to execute the epilogue, if the VM operation object is getting |
689 // deallocated by the VM thread. |
684 // deallocated by the VM thread. |
690 bool execute_epilog = !op->is_cheap_allocated(); |
685 bool execute_epilog = !op->is_cheap_allocated(); |
691 assert(!concurrent || op->is_cheap_allocated(), "concurrent => cheap_allocated"); |
686 assert(!concurrent || op->is_cheap_allocated(), "concurrent => cheap_allocated"); |
698 |
693 |
699 // Add VM operation to list of waiting threads. We are guaranteed not to block while holding the |
694 // Add VM operation to list of waiting threads. We are guaranteed not to block while holding the |
700 // VMOperationQueue_lock, so we can block without a safepoint check. This allows vm operation requests |
695 // VMOperationQueue_lock, so we can block without a safepoint check. This allows vm operation requests |
701 // to be queued up during a safepoint synchronization. |
696 // to be queued up during a safepoint synchronization. |
702 { |
697 { |
703 VMOperationQueue_lock->lock_without_safepoint_check(); |
698 MonitorLocker ml(VMOperationQueue_lock, Mutex::_no_safepoint_check_flag); |
704 log_debug(vmthread)("Adding VM operation: %s", op->name()); |
699 log_debug(vmthread)("Adding VM operation: %s", op->name()); |
705 bool ok = _vm_queue->add(op); |
700 _vm_queue->add(op); |
706 op->set_timestamp(os::javaTimeMillis()); |
701 op->set_timestamp(os::javaTimeMillis()); |
707 VMOperationQueue_lock->notify(); |
702 ml.notify(); |
708 VMOperationQueue_lock->unlock(); |
|
709 // VM_Operation got skipped |
|
710 if (!ok) { |
|
711 assert(concurrent, "can only skip concurrent tasks"); |
|
712 if (op->is_cheap_allocated()) delete op; |
|
713 return; |
|
714 } |
|
715 } |
703 } |
716 |
704 |
717 if (!concurrent) { |
705 if (!concurrent) { |
718 // Wait for completion of request (non-concurrent) |
706 // Wait for completion of request (non-concurrent) |
719 // Note: only a JavaThread triggers the safepoint check when locking |
707 // Note: only a JavaThread triggers the safepoint check when locking |
736 // does not allow nested scavenges or compiles. |
724 // does not allow nested scavenges or compiles. |
737 if (!prev_vm_operation->allow_nested_vm_operations()) { |
725 if (!prev_vm_operation->allow_nested_vm_operations()) { |
738 fatal("Nested VM operation %s requested by operation %s", |
726 fatal("Nested VM operation %s requested by operation %s", |
739 op->name(), vm_operation()->name()); |
727 op->name(), vm_operation()->name()); |
740 } |
728 } |
741 op->set_calling_thread(prev_vm_operation->calling_thread(), prev_vm_operation->priority()); |
729 op->set_calling_thread(prev_vm_operation->calling_thread()); |
742 } |
730 } |
743 |
731 |
744 EventMark em("Executing %s VM operation: %s", prev_vm_operation ? "nested" : "", op->name()); |
732 EventMark em("Executing %s VM operation: %s", prev_vm_operation ? "nested" : "", op->name()); |
745 |
733 |
746 // Release all internal handles after operation is evaluated |
734 // Release all internal handles after operation is evaluated |