< prev index next >

src/share/vm/runtime/safepoint.cpp

Print this page
rev 13053 : 8180932: Parallelize safepoint cleanup
Summary: Provide infrastructure to do safepoint cleanup tasks using parallel worker threads
Reviewed-by: dholmes, rehn


 521   if (event.should_commit()) {
 522     event.set_safepointId(safepoint_id);
 523     event.commit();
 524   }
 525 }
 526 
 527 bool SafepointSynchronize::is_cleanup_needed() {
 528   // Need a safepoint if some inline cache buffers is non-empty
 529   if (!InlineCacheBuffer::is_empty()) return true;
 530   return false;
 531 }
 532 
 533 static void event_safepoint_cleanup_task_commit(EventSafepointCleanupTask& event, const char* name) {
 534   if (event.should_commit()) {
 535     event.set_safepointId(SafepointSynchronize::safepoint_counter());
 536     event.set_name(name);
 537     event.commit();
 538   }
 539 }
 540 
 541 // Various cleaning tasks that should be done periodically at safepoints
 542 void SafepointSynchronize::do_cleanup_tasks() {
 543   {

































 544     const char* name = "deflating idle monitors";
 545     EventSafepointCleanupTask event;
 546     TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
 547     ObjectSynchronizer::deflate_idle_monitors();
 548     event_safepoint_cleanup_task_commit(event, name);
 549   }
 550 
 551   {
 552     const char* name = "updating inline caches";
 553     EventSafepointCleanupTask event;
 554     TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
 555     InlineCacheBuffer::update_inline_caches();
 556     event_safepoint_cleanup_task_commit(event, name);
 557   }
 558   {

 559     const char* name = "compilation policy safepoint handler";
 560     EventSafepointCleanupTask event;
 561     TraceTime timer("compilation policy safepoint handler", TRACETIME_LOG(Info, safepoint, cleanup));
 562     CompilationPolicy::policy()->do_safepoint_work();
 563     event_safepoint_cleanup_task_commit(event, name);
 564   }
 565 
 566   {
 567     const char* name = "mark nmethods";
 568     EventSafepointCleanupTask event;
 569     TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
 570     NMethodSweeper::mark_active_nmethods();
 571     event_safepoint_cleanup_task_commit(event, name);
 572   }
 573 
 574   if (SymbolTable::needs_rehashing()) {
 575     const char* name = "rehashing symbol table";
 576     EventSafepointCleanupTask event;
 577     TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
 578     SymbolTable::rehash_table();
 579     event_safepoint_cleanup_task_commit(event, name);
 580   }

 581 

 582   if (StringTable::needs_rehashing()) {
 583     const char* name = "rehashing string table";
 584     EventSafepointCleanupTask event;
 585     TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
 586     StringTable::rehash_table();
 587     event_safepoint_cleanup_task_commit(event, name);
 588   }

 589 
 590   {
 591     // CMS delays purging the CLDG until the beginning of the next safepoint and to
 592     // make sure concurrent sweep is done
 593     const char* name = "purging class loader data graph";
 594     EventSafepointCleanupTask event;
 595     TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
 596     ClassLoaderDataGraph::purge_if_needed();
 597     event_safepoint_cleanup_task_commit(event, name);





















 598   }
 599 }
 600 
 601 
 602 bool SafepointSynchronize::safepoint_safe(JavaThread *thread, JavaThreadState state) {
 603   switch(state) {
 604   case _thread_in_native:
 605     // native threads are safe if they have no java stack or have walkable stack
 606     return !thread->has_last_Java_frame() || thread->frame_anchor()->walkable();
 607 
 608    // blocked threads should have already have walkable stack
 609   case _thread_blocked:
 610     assert(!thread->has_last_Java_frame() || thread->frame_anchor()->walkable(), "blocked and not walkable");
 611     return true;
 612 
 613   default:
 614     return false;
 615   }
 616 }
 617 




 521   if (event.should_commit()) {
 522     event.set_safepointId(safepoint_id);
 523     event.commit();
 524   }
 525 }
 526 
 527 bool SafepointSynchronize::is_cleanup_needed() {
 528   // Need a safepoint if some inline cache buffers is non-empty
 529   if (!InlineCacheBuffer::is_empty()) return true;
 530   return false;
 531 }
 532 
 533 static void event_safepoint_cleanup_task_commit(EventSafepointCleanupTask& event, const char* name) {
 534   if (event.should_commit()) {
 535     event.set_safepointId(SafepointSynchronize::safepoint_counter());
 536     event.set_name(name);
 537     event.commit();
 538   }
 539 }
 540 
 541 class ParallelSPCleanupThreadClosure : public ThreadClosure {
 542 private:
 543   CodeBlobClosure* _nmethod_cl;
 544 
 545 public:
 546   ParallelSPCleanupThreadClosure() {
 547     _nmethod_cl = NMethodSweeper::prepare_mark_active_nmethods();
 548   }
 549 
 550   void do_thread(Thread* thread) {
 551     ObjectSynchronizer::deflate_thread_local_monitors(thread);
 552     if (_nmethod_cl != NULL && thread->is_Java_thread() &&
 553         ! thread->is_Code_cache_sweeper_thread()) {
 554       JavaThread* jt = (JavaThread*) thread;
 555       jt->nmethods_do(_nmethod_cl);
 556     }
 557   }
 558 };
 559 
 560 class ParallelSPCleanupTask : public AbstractGangTask {
 561 private:
 562   SubTasksDone _subtasks;
 563   ParallelSPCleanupThreadClosure _cleanup_threads_cl;
 564   uint _num_workers;
 565 public:
 566   ParallelSPCleanupTask(uint num_workers) :
 567     AbstractGangTask("Parallel Safepoint Cleanup"),
 568     _cleanup_threads_cl(ParallelSPCleanupThreadClosure()),
 569     _num_workers(num_workers),
 570     _subtasks(SubTasksDone(SafepointSynchronize::SAFEPOINT_CLEANUP_NUM_TASKS)) {}
 571 
 572   void work(uint worker_id) {
 573     // All threads deflate monitors and mark nmethods (if necessary).
 574     Threads::parallel_java_threads_do(&_cleanup_threads_cl);
 575 
 576     if (! _subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_DEFLATE_MONITORS)) {
 577       const char* name = "deflating idle monitors";
 578       EventSafepointCleanupTask event;
 579       TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
 580       ObjectSynchronizer::deflate_idle_monitors();
 581       event_safepoint_cleanup_task_commit(event, name);
 582     }
 583 
 584     if (! _subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_UPDATE_INLINE_CACHES)) {
 585       const char* name = "updating inline caches";
 586       EventSafepointCleanupTask event;
 587       TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
 588       InlineCacheBuffer::update_inline_caches();
 589       event_safepoint_cleanup_task_commit(event, name);
 590     }
 591 
 592     if (! _subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_COMPILATION_POLICY)) {
 593       const char* name = "compilation policy safepoint handler";
 594       EventSafepointCleanupTask event;
 595       TraceTime timer("compilation policy safepoint handler", TRACETIME_LOG(Info, safepoint, cleanup));
 596       CompilationPolicy::policy()->do_safepoint_work();
 597       event_safepoint_cleanup_task_commit(event, name);
 598     }
 599 
 600     if (! _subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_SYMBOL_TABLE_REHASH)) {







 601       if (SymbolTable::needs_rehashing()) {
 602         const char* name = "rehashing symbol table";
 603         EventSafepointCleanupTask event;
 604         TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
 605         SymbolTable::rehash_table();
 606         event_safepoint_cleanup_task_commit(event, name);
 607       }
 608     }
 609 
 610     if (! _subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_STRING_TABLE_REHASH)) {
 611       if (StringTable::needs_rehashing()) {
 612         const char* name = "rehashing string table";
 613         EventSafepointCleanupTask event;
 614         TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
 615         StringTable::rehash_table();
 616         event_safepoint_cleanup_task_commit(event, name);
 617       }
 618     }
 619 
 620     if (! _subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_CLD_PURGE)) {
 621       // CMS delays purging the CLDG until the beginning of the next safepoint and to
 622       // make sure concurrent sweep is done
 623       const char* name = "purging class loader data graph";
 624       EventSafepointCleanupTask event;
 625       TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
 626       ClassLoaderDataGraph::purge_if_needed();
 627       event_safepoint_cleanup_task_commit(event, name);
 628     }
 629     _subtasks.all_tasks_completed(_num_workers);
 630   }
 631 };
 632 
 633 // Various cleaning tasks that should be done periodically at safepoints
 634 void SafepointSynchronize::do_cleanup_tasks() {
 635   CollectedHeap* heap = Universe::heap();
 636   assert(heap != NULL, "heap not initialized yet?");
 637   WorkGang* cleanup_workers = heap->get_safepoint_workers();
 638   if (cleanup_workers != NULL) {
 639     // Parallel cleanup using GC provided thread pool.
 640     uint num_cleanup_workers = cleanup_workers->active_workers();
 641     ParallelSPCleanupTask cleanup(num_cleanup_workers);
 642     StrongRootsScope srs(num_cleanup_workers);
 643     cleanup_workers->run_task(&cleanup);
 644   } else {
 645     // Serial cleanup using VMThread.
 646     ParallelSPCleanupTask cleanup(1);
 647     StrongRootsScope srs(1);
 648     cleanup.work(0);
 649   }
 650 }
 651 
 652 
 653 bool SafepointSynchronize::safepoint_safe(JavaThread *thread, JavaThreadState state) {
 654   switch(state) {
 655   case _thread_in_native:
 656     // native threads are safe if they have no java stack or have walkable stack
 657     return !thread->has_last_Java_frame() || thread->frame_anchor()->walkable();
 658 
 659    // blocked threads should have already have walkable stack
 660   case _thread_blocked:
 661     assert(!thread->has_last_Java_frame() || thread->frame_anchor()->walkable(), "blocked and not walkable");
 662     return true;
 663 
 664   default:
 665     return false;
 666   }
 667 }
 668 


< prev index next >