< prev index next >

src/hotspot/share/runtime/vmThread.cpp

Print this page
rev 54213 : [mq]: 8220774-handshakealot-v3


 417                      op->evaluation_mode());
 418   }
 419 
 420   // Last access of info in _cur_vm_operation!
 421   bool c_heap_allocated = op->is_cheap_allocated();
 422 
 423   // Mark as completed
 424   if (!op->evaluate_concurrently()) {
 425     op->calling_thread()->increment_vm_operation_completed_count();
 426   }
 427   // It is unsafe to access the _cur_vm_operation after the 'increment_vm_operation_completed_count' call,
 428   // since if it is stack allocated the calling thread might have deallocated
 429   if (c_heap_allocated) {
 430     delete _cur_vm_operation;
 431   }
 432 }
 433 
 434 static VM_None    safepointALot_op("SafepointALot");
 435 static VM_Cleanup cleanup_op;
 436 
 437 VM_Operation* VMThread::no_op_safepoint(bool check_time) {
 438   if (SafepointALot) {
 439     return &safepointALot_op;
 440   }
 441   if (!SafepointSynchronize::is_cleanup_needed()) {
 442     return NULL;










 443   }
 444   if (check_time) {
 445     long interval_ms = SafepointTracing::time_since_last_safepoint_ms();
 446     bool max_time_exceeded = GuaranteedSafepointInterval != 0 &&
 447                              (interval_ms > GuaranteedSafepointInterval);
 448     if (!max_time_exceeded) {
 449       return NULL;
 450     }


 451   }
 452   return &cleanup_op;

 453 }
 454 
 455 void VMThread::loop() {
 456   assert(_cur_vm_operation == NULL, "no current one should be executing");
 457 
 458   SafepointSynchronize::init(_vm_thread);
 459 
 460   while(true) {
 461     VM_Operation* safepoint_ops = NULL;
 462     //
 463     // Wait for VM operation
 464     //
 465     // use no_safepoint_check to get lock without attempting to "sneak"
 466     { MutexLockerEx mu_queue(VMOperationQueue_lock,
 467                              Mutex::_no_safepoint_check_flag);
 468 
 469       // Look for new operation
 470       assert(_cur_vm_operation == NULL, "no current one should be executing");
 471       _cur_vm_operation = _vm_queue->remove_next();
 472 


 474       if (PrintVMQWaitTime && _cur_vm_operation != NULL &&
 475           !_cur_vm_operation->evaluate_concurrently()) {
 476         long stall = os::javaTimeMillis() - _cur_vm_operation->timestamp();
 477         if (stall > 0)
 478           tty->print_cr("%s stall: %ld",  _cur_vm_operation->name(), stall);
 479       }
 480 
 481       while (!should_terminate() && _cur_vm_operation == NULL) {
 482         // wait with a timeout to guarantee safepoints at regular intervals
 483         bool timedout =
 484           VMOperationQueue_lock->wait(Mutex::_no_safepoint_check_flag,
 485                                       GuaranteedSafepointInterval);
 486 
 487         // Support for self destruction
 488         if ((SelfDestructTimer != 0) && !VMError::is_error_reported() &&
 489             (os::elapsedTime() > (double)SelfDestructTimer * 60.0)) {
 490           tty->print_cr("VM self-destructed");
 491           exit(-1);
 492         }
 493 
 494         if (timedout && (_cur_vm_operation = VMThread::no_op_safepoint(false)) != NULL) {
 495           MutexUnlockerEx mul(VMOperationQueue_lock,
 496                               Mutex::_no_safepoint_check_flag);


 497           // Force a safepoint since we have not had one for at least
 498           // 'GuaranteedSafepointInterval' milliseconds.  This will run all
 499           // the clean-up processing that needs to be done regularly at a
 500           // safepoint
 501           SafepointSynchronize::begin();
 502           #ifdef ASSERT
 503             if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
 504           #endif
 505           SafepointSynchronize::end();
 506           _cur_vm_operation = NULL;
 507         }

 508         _cur_vm_operation = _vm_queue->remove_next();
 509 
 510         // If we are at a safepoint we will evaluate all the operations that
 511         // follow that also require a safepoint
 512         if (_cur_vm_operation != NULL &&
 513             _cur_vm_operation->evaluate_at_safepoint()) {
 514           safepoint_ops = _vm_queue->drain_at_safepoint_priority();
 515         }
 516       }
 517 
 518       if (should_terminate()) break;
 519     } // Release mu_queue_lock
 520 
 521     //
 522     // Execute VM operation
 523     //
 524     { HandleMark hm(VMThread::vm_thread());
 525 
 526       EventMark em("Executing VM operation: %s", vm_operation()->name());
 527       assert(_cur_vm_operation != NULL, "we should have found an operation to execute");


 601           }
 602         } else {
 603           evaluate_operation(_cur_vm_operation);
 604         }
 605 
 606         _cur_vm_operation = NULL;
 607       }
 608     }
 609 
 610     //
 611     //  Notify (potential) waiting Java thread(s) - lock without safepoint
 612     //  check so that sneaking is not possible
 613     { MutexLockerEx mu(VMOperationRequest_lock,
 614                        Mutex::_no_safepoint_check_flag);
 615       VMOperationRequest_lock->notify_all();
 616     }
 617 
 618     //
 619     // We want to make sure that we get to a safepoint regularly.
 620     //
 621     if ((_cur_vm_operation = VMThread::no_op_safepoint(false)) != NULL) {
 622       HandleMark hm(VMThread::vm_thread());
 623       SafepointSynchronize::begin();
 624       SafepointSynchronize::end();
 625       _cur_vm_operation = NULL;
 626     }
 627   }
 628 }
 629 
 630 // A SkipGCALot object is used to elide the usual effect of gc-a-lot
 631 // over a section of execution by a thread. Currently, it's used only to
 632 // prevent re-entrant calls to GC.
 633 class SkipGCALot : public StackObj {
 634   private:
 635    bool _saved;
 636    Thread* _t;
 637 
 638   public:
 639 #ifdef ASSERT
 640     SkipGCALot(Thread* t) : _t(t) {
 641       _saved = _t->skip_gcalot();




 417                      op->evaluation_mode());
 418   }
 419 
 420   // Last access of info in _cur_vm_operation!
 421   bool c_heap_allocated = op->is_cheap_allocated();
 422 
 423   // Mark as completed
 424   if (!op->evaluate_concurrently()) {
 425     op->calling_thread()->increment_vm_operation_completed_count();
 426   }
 427   // It is unsafe to access the _cur_vm_operation after the 'increment_vm_operation_completed_count' call,
 428   // since if it is stack allocated the calling thread might have deallocated
 429   if (c_heap_allocated) {
 430     delete _cur_vm_operation;
 431   }
 432 }
 433 
 434 static VM_None    safepointALot_op("SafepointALot");
 435 static VM_Cleanup cleanup_op;
 436 
 437 class HandshakeALotTC : public ThreadClosure {
 438  public:
 439   virtual void do_thread(Thread* thread) {
 440 #ifdef ASSERT
 441     assert(thread->is_Java_thread(), "must be");
 442     JavaThread* jt = (JavaThread*)thread;
 443     jt->verify_states_for_handshake();
 444 #endif
 445   }
 446 };
 447 
 448 VM_Operation* VMThread::no_op_safepoint() {
 449   // Must check for handshakes first, since ops returns.
 450   if (HandshakeALot) {
 451     HandshakeALotTC haltc;
 452     Handshake::execute(&haltc);
 453   }
 454   // Check for a true cleanup first, trying to keep stats correct.
 455   long interval_ms = SafepointTracing::time_since_last_safepoint_ms();
 456   bool max_time_exceeded = GuaranteedSafepointInterval != 0 &&
 457                            (interval_ms >= GuaranteedSafepointInterval);
 458   if (max_time_exceeded && SafepointSynchronize::is_cleanup_needed()) {
 459     return &cleanup_op;
 460   }
 461   if (SafepointALot) {
 462     return &safepointALot_op;
 463   }
 464   // Nothing to be done.
 465   return NULL;
 466 }
 467 
 468 void VMThread::loop() {
 469   assert(_cur_vm_operation == NULL, "no current one should be executing");
 470 
 471   SafepointSynchronize::init(_vm_thread);
 472 
 473   while(true) {
 474     VM_Operation* safepoint_ops = NULL;
 475     //
 476     // Wait for VM operation
 477     //
 478     // use no_safepoint_check to get lock without attempting to "sneak"
 479     { MutexLockerEx mu_queue(VMOperationQueue_lock,
 480                              Mutex::_no_safepoint_check_flag);
 481 
 482       // Look for new operation
 483       assert(_cur_vm_operation == NULL, "no current one should be executing");
 484       _cur_vm_operation = _vm_queue->remove_next();
 485 


 487       if (PrintVMQWaitTime && _cur_vm_operation != NULL &&
 488           !_cur_vm_operation->evaluate_concurrently()) {
 489         long stall = os::javaTimeMillis() - _cur_vm_operation->timestamp();
 490         if (stall > 0)
 491           tty->print_cr("%s stall: %ld",  _cur_vm_operation->name(), stall);
 492       }
 493 
 494       while (!should_terminate() && _cur_vm_operation == NULL) {
 495         // wait with a timeout to guarantee safepoints at regular intervals
 496         bool timedout =
 497           VMOperationQueue_lock->wait(Mutex::_no_safepoint_check_flag,
 498                                       GuaranteedSafepointInterval);
 499 
 500         // Support for self destruction
 501         if ((SelfDestructTimer != 0) && !VMError::is_error_reported() &&
 502             (os::elapsedTime() > (double)SelfDestructTimer * 60.0)) {
 503           tty->print_cr("VM self-destructed");
 504           exit(-1);
 505         }
 506 
 507         {
 508           // Have to unlock VMOperationQueue_lock just in case no_op_safepoint()
 509           // has to do a handshake.
 510           MutexUnlockerEx mul(VMOperationQueue_lock, Mutex::_no_safepoint_check_flag);
 511           if (timedout && (_cur_vm_operation = VMThread::no_op_safepoint()) != NULL) {
 512             // Force a safepoint since we have not had one for at least
 513             // 'GuaranteedSafepointInterval' milliseconds and we need to clean
 514             // something. This will run all the clean-up processing that needs
 515             // to be done at a safepoint.
 516             SafepointSynchronize::begin();
 517             #ifdef ASSERT
 518               if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
 519             #endif
 520             SafepointSynchronize::end();
 521             _cur_vm_operation = NULL;
 522           }
 523         }
 524         _cur_vm_operation = _vm_queue->remove_next();
 525 
 526         // If we are at a safepoint we will evaluate all the operations that
 527         // follow that also require a safepoint
 528         if (_cur_vm_operation != NULL &&
 529             _cur_vm_operation->evaluate_at_safepoint()) {
 530           safepoint_ops = _vm_queue->drain_at_safepoint_priority();
 531         }
 532       }
 533 
 534       if (should_terminate()) break;
 535     } // Release mu_queue_lock
 536 
 537     //
 538     // Execute VM operation
 539     //
 540     { HandleMark hm(VMThread::vm_thread());
 541 
 542       EventMark em("Executing VM operation: %s", vm_operation()->name());
 543       assert(_cur_vm_operation != NULL, "we should have found an operation to execute");


 617           }
 618         } else {
 619           evaluate_operation(_cur_vm_operation);
 620         }
 621 
 622         _cur_vm_operation = NULL;
 623       }
 624     }
 625 
 626     //
 627     //  Notify (potential) waiting Java thread(s) - lock without safepoint
 628     //  check so that sneaking is not possible
 629     { MutexLockerEx mu(VMOperationRequest_lock,
 630                        Mutex::_no_safepoint_check_flag);
 631       VMOperationRequest_lock->notify_all();
 632     }
 633 
 634     //
 635     // We want to make sure that we get to a safepoint regularly.
 636     //
 637     if ((_cur_vm_operation = VMThread::no_op_safepoint()) != NULL) {
 638       HandleMark hm(VMThread::vm_thread());
 639       SafepointSynchronize::begin();
 640       SafepointSynchronize::end();
 641       _cur_vm_operation = NULL;
 642     }
 643   }
 644 }
 645 
 646 // A SkipGCALot object is used to elide the usual effect of gc-a-lot
 647 // over a section of execution by a thread. Currently, it's used only to
 648 // prevent re-entrant calls to GC.
 649 class SkipGCALot : public StackObj {
 650   private:
 651    bool _saved;
 652    Thread* _t;
 653 
 654   public:
 655 #ifdef ASSERT
 656     SkipGCALot(Thread* t) : _t(t) {
 657       _saved = _t->skip_gcalot();


< prev index next >