src/share/vm/runtime/vmThread.cpp

Print this page
rev 5878 : [mq]: usdt1-gone


  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "compiler/compileBroker.hpp"
  27 #include "gc_interface/collectedHeap.hpp"
  28 #include "memory/resourceArea.hpp"
  29 #include "oops/method.hpp"
  30 #include "oops/oop.inline.hpp"
  31 #include "runtime/interfaceSupport.hpp"
  32 #include "runtime/mutexLocker.hpp"
  33 #include "runtime/os.hpp"
  34 #include "runtime/thread.inline.hpp"
  35 #include "runtime/vmThread.hpp"
  36 #include "runtime/vm_operations.hpp"
  37 #include "services/runtimeService.hpp"
  38 #include "trace/tracing.hpp"
  39 #include "utilities/dtrace.hpp"
  40 #include "utilities/events.hpp"
  41 #include "utilities/xmlstream.hpp"
  42 
  43 #ifndef USDT2
  44 HS_DTRACE_PROBE_DECL3(hotspot, vmops__request, char *, uintptr_t, int);
  45 HS_DTRACE_PROBE_DECL3(hotspot, vmops__begin, char *, uintptr_t, int);
  46 HS_DTRACE_PROBE_DECL3(hotspot, vmops__end, char *, uintptr_t, int);
  47 #endif /* !USDT2 */
  48 
  49 // Dummy VM operation to act as first element in our circular double-linked list
  50 class VM_Dummy: public VM_Operation {
  51   VMOp_Type type() const { return VMOp_Dummy; }
  52   void  doit() {};
  53 };
  54 
  55 VMOperationQueue::VMOperationQueue() {
  56   // The queue is a circular doubled-linked list, which always contains
  57   // one element (i.e., one element means empty).
  58   for(int i = 0; i < nof_priorities; i++) {
  59     _queue_length[i] = 0;
  60     _queue_counter = 0;
  61     _queue[i] = new VM_Dummy();
  62     _queue[i]->set_next(_queue[i]);
  63     _queue[i]->set_prev(_queue[i]);
  64   }
  65   _drain_list = NULL;
  66 }
  67 
  68 


 137   VM_Operation* cur = _queue[queue];
 138   cur = cur->next();
 139   while (cur != _queue[queue]) {
 140     cur->oops_do(f);
 141     cur = cur->next();
 142   }
 143 }
 144 
 145 void VMOperationQueue::drain_list_oops_do(OopClosure* f) {
 146   VM_Operation* cur = _drain_list;
 147   while (cur != NULL) {
 148     cur->oops_do(f);
 149     cur = cur->next();
 150   }
 151 }
 152 
 153 //-----------------------------------------------------------------
 154 // High-level interface
 155 bool VMOperationQueue::add(VM_Operation *op) {
 156 
 157 #ifndef USDT2
 158   HS_DTRACE_PROBE3(hotspot, vmops__request, op->name(), strlen(op->name()),
 159                    op->evaluation_mode());
 160 #else /* USDT2 */
 161   HOTSPOT_VMOPS_REQUEST(
 162                    (char *) op->name(), strlen(op->name()),
 163                    op->evaluation_mode());
 164 #endif /* USDT2 */
 165 
 166   // Encapsulates VM queue policy. Currently, that
 167   // only involves putting them on the right list
 168   if (op->evaluate_at_safepoint()) {
 169     queue_add_back(SafepointPriority, op);
 170     return true;
 171   }
 172 
 173   queue_add_back(MediumPriority, op);
 174   return true;
 175 }
 176 
 177 VM_Operation* VMOperationQueue::remove_next() {
 178   // Assuming VMOperation queue is two-level priority queue. If there are
 179   // more than two priorities, we need a different scheduling algorithm.
 180   assert(SafepointPriority == 0 && MediumPriority == 1 && nof_priorities == 2,
 181          "current algorithm does not work");
 182 
 183   // simple counter based scheduling to prevent starvation of lower priority
 184   // queue. -- see 4390175


 341   // at a very delicate time (VM shutdown) and we are operating in non- VM
 342   // thread at Safepoint. It's safer to not share lock with other threads.
 343   { MutexLockerEx ml(_terminate_lock, Mutex::_no_safepoint_check_flag);
 344     while(!VMThread::is_terminated()) {
 345         _terminate_lock->wait(Mutex::_no_safepoint_check_flag);
 346     }
 347   }
 348 }
 349 
 350 void VMThread::print_on(outputStream* st) const {
 351   st->print("\"%s\" ", name());
 352   Thread::print_on(st);
 353   st->cr();
 354 }
 355 
 356 void VMThread::evaluate_operation(VM_Operation* op) {
 357   ResourceMark rm;
 358 
 359   {
 360     PerfTraceTime vm_op_timer(perf_accumulated_vm_operation_time());
 361 #ifndef USDT2
 362     HS_DTRACE_PROBE3(hotspot, vmops__begin, op->name(), strlen(op->name()),
 363                      op->evaluation_mode());
 364 #else /* USDT2 */
 365     HOTSPOT_VMOPS_BEGIN(
 366                      (char *) op->name(), strlen(op->name()),
 367                      op->evaluation_mode());
 368 #endif /* USDT2 */
 369 
 370     EventExecuteVMOperation event;
 371 
 372     op->evaluate();
 373 
 374     if (event.should_commit()) {
 375       bool is_concurrent = op->evaluate_concurrently();
 376       event.set_operation(op->type());
 377       event.set_safepoint(op->evaluate_at_safepoint());
 378       event.set_blocking(!is_concurrent);
 379       // Only write caller thread information for non-concurrent vm operations.
 380       // For concurrent vm operations, the thread id is set to 0 indicating thread is unknown.
 381       // This is because the caller thread could have exited already.
 382       event.set_caller(is_concurrent ? 0 : op->calling_thread()->osthread()->thread_id());
 383       event.commit();
 384     }
 385 
 386 #ifndef USDT2
 387     HS_DTRACE_PROBE3(hotspot, vmops__end, op->name(), strlen(op->name()),
 388                      op->evaluation_mode());
 389 #else /* USDT2 */
 390     HOTSPOT_VMOPS_END(
 391                      (char *) op->name(), strlen(op->name()),
 392                      op->evaluation_mode());
 393 #endif /* USDT2 */
 394   }
 395 
 396   // Last access of info in _cur_vm_operation!
 397   bool c_heap_allocated = op->is_cheap_allocated();
 398 
 399   // Mark as completed
 400   if (!op->evaluate_concurrently()) {
 401     op->calling_thread()->increment_vm_operation_completed_count();
 402   }
 403   // It is unsafe to access the _cur_vm_operation after the 'increment_vm_operation_completed_count' call,
 404   // since if it is stack allocated the calling thread might have deallocated
 405   if (c_heap_allocated) {
 406     delete _cur_vm_operation;
 407   }
 408 }
 409 
 410 
 411 void VMThread::loop() {
 412   assert(_cur_vm_operation == NULL, "no current one should be executing");
 413 




  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "compiler/compileBroker.hpp"
  27 #include "gc_interface/collectedHeap.hpp"
  28 #include "memory/resourceArea.hpp"
  29 #include "oops/method.hpp"
  30 #include "oops/oop.inline.hpp"
  31 #include "runtime/interfaceSupport.hpp"
  32 #include "runtime/mutexLocker.hpp"
  33 #include "runtime/os.hpp"
  34 #include "runtime/thread.inline.hpp"
  35 #include "runtime/vmThread.hpp"
  36 #include "runtime/vm_operations.hpp"
  37 #include "services/runtimeService.hpp"
  38 #include "trace/tracing.hpp"
  39 #include "utilities/dtrace.hpp"
  40 #include "utilities/events.hpp"
  41 #include "utilities/xmlstream.hpp"
  42 






  43 // Dummy VM operation to act as first element in our circular double-linked list
  44 class VM_Dummy: public VM_Operation {
  45   VMOp_Type type() const { return VMOp_Dummy; }
  46   void  doit() {};
  47 };
  48 
  49 VMOperationQueue::VMOperationQueue() {
  50   // The queue is a circular doubled-linked list, which always contains
  51   // one element (i.e., one element means empty).
  52   for(int i = 0; i < nof_priorities; i++) {
  53     _queue_length[i] = 0;
  54     _queue_counter = 0;
  55     _queue[i] = new VM_Dummy();
  56     _queue[i]->set_next(_queue[i]);
  57     _queue[i]->set_prev(_queue[i]);
  58   }
  59   _drain_list = NULL;
  60 }
  61 
  62 


 131   VM_Operation* cur = _queue[queue];
 132   cur = cur->next();
 133   while (cur != _queue[queue]) {
 134     cur->oops_do(f);
 135     cur = cur->next();
 136   }
 137 }
 138 
 139 void VMOperationQueue::drain_list_oops_do(OopClosure* f) {
 140   VM_Operation* cur = _drain_list;
 141   while (cur != NULL) {
 142     cur->oops_do(f);
 143     cur = cur->next();
 144   }
 145 }
 146 
 147 //-----------------------------------------------------------------
 148 // High-level interface
 149 bool VMOperationQueue::add(VM_Operation *op) {
 150 




 151   HOTSPOT_VMOPS_REQUEST(
 152                    (char *) op->name(), strlen(op->name()),
 153                    op->evaluation_mode());

 154 
 155   // Encapsulates VM queue policy. Currently, that
 156   // only involves putting them on the right list
 157   if (op->evaluate_at_safepoint()) {
 158     queue_add_back(SafepointPriority, op);
 159     return true;
 160   }
 161 
 162   queue_add_back(MediumPriority, op);
 163   return true;
 164 }
 165 
 166 VM_Operation* VMOperationQueue::remove_next() {
 167   // Assuming VMOperation queue is two-level priority queue. If there are
 168   // more than two priorities, we need a different scheduling algorithm.
 169   assert(SafepointPriority == 0 && MediumPriority == 1 && nof_priorities == 2,
 170          "current algorithm does not work");
 171 
 172   // simple counter based scheduling to prevent starvation of lower priority
 173   // queue. -- see 4390175


 330   // at a very delicate time (VM shutdown) and we are operating in non- VM
 331   // thread at Safepoint. It's safer to not share lock with other threads.
 332   { MutexLockerEx ml(_terminate_lock, Mutex::_no_safepoint_check_flag);
 333     while(!VMThread::is_terminated()) {
 334         _terminate_lock->wait(Mutex::_no_safepoint_check_flag);
 335     }
 336   }
 337 }
 338 
 339 void VMThread::print_on(outputStream* st) const {
 340   st->print("\"%s\" ", name());
 341   Thread::print_on(st);
 342   st->cr();
 343 }
 344 
 345 void VMThread::evaluate_operation(VM_Operation* op) {
 346   ResourceMark rm;
 347 
 348   {
 349     PerfTraceTime vm_op_timer(perf_accumulated_vm_operation_time());




 350     HOTSPOT_VMOPS_BEGIN(
 351                      (char *) op->name(), strlen(op->name()),
 352                      op->evaluation_mode());

 353 
 354     EventExecuteVMOperation event;
 355 
 356     op->evaluate();
 357 
 358     if (event.should_commit()) {
 359       bool is_concurrent = op->evaluate_concurrently();
 360       event.set_operation(op->type());
 361       event.set_safepoint(op->evaluate_at_safepoint());
 362       event.set_blocking(!is_concurrent);
 363       // Only write caller thread information for non-concurrent vm operations.
 364       // For concurrent vm operations, the thread id is set to 0 indicating thread is unknown.
 365       // This is because the caller thread could have exited already.
 366       event.set_caller(is_concurrent ? 0 : op->calling_thread()->osthread()->thread_id());
 367       event.commit();
 368     }
 369 




 370     HOTSPOT_VMOPS_END(
 371                      (char *) op->name(), strlen(op->name()),
 372                      op->evaluation_mode());

 373   }
 374 
 375   // Last access of info in _cur_vm_operation!
 376   bool c_heap_allocated = op->is_cheap_allocated();
 377 
 378   // Mark as completed
 379   if (!op->evaluate_concurrently()) {
 380     op->calling_thread()->increment_vm_operation_completed_count();
 381   }
 382   // It is unsafe to access the _cur_vm_operation after the 'increment_vm_operation_completed_count' call,
 383   // since if it is stack allocated the calling thread might have deallocated
 384   if (c_heap_allocated) {
 385     delete _cur_vm_operation;
 386   }
 387 }
 388 
 389 
 390 void VMThread::loop() {
 391   assert(_cur_vm_operation == NULL, "no current one should be executing");
 392