< prev index next >

src/share/vm/runtime/safepoint.cpp

Print this page
rev 13387 : [mq]: parallel_sp_cleaning.patch

*** 70,79 **** --- 70,81 ---- #endif // -------------------------------------------------------------------------------------------------- // Implementation of Safepoint begin/end + WorkGang* SafepointSynchronize::_cleanup_workers = NULL; + SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized; volatile int SafepointSynchronize::_waiting_to_block = 0; volatile int SafepointSynchronize::_safepoint_counter = 0; int SafepointSynchronize::_current_jni_active_count = 0; long SafepointSynchronize::_end_of_last_safepoint = 0;
*** 541,555 **** } } // Various cleaning tasks that should be done periodically at safepoints void SafepointSynchronize::do_cleanup_tasks() { { const char* name = "deflating idle monitors"; EventSafepointCleanupTask event; TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); ! ObjectSynchronizer::deflate_idle_monitors(); event_safepoint_cleanup_task_commit(event, name); } { const char* name = "updating inline caches"; --- 543,570 ---- } } // Various cleaning tasks that should be done periodically at safepoints void SafepointSynchronize::do_cleanup_tasks() { + VM_Operation* op = VMThread::vm_operation(); + // If op does both deflating and nmethod marking, we don't bother firing up + // the workers. + bool op_does_cleanup = op != NULL && op->marks_nmethods() && op->deflates_idle_monitors(); + if (ParallelSPCleanup && ! op_does_cleanup) { + parallel_cleanup(); + } else { + serial_cleanup(); + } + } + + void SafepointSynchronize::serial_cleanup() { + VM_Operation* op = VMThread::vm_operation(); { const char* name = "deflating idle monitors"; EventSafepointCleanupTask event; TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); ! ObjectSynchronizer::deflate_idle_monitors(op == NULL || ! op->deflates_idle_monitors()); event_safepoint_cleanup_task_commit(event, name); } { const char* name = "updating inline caches";
*** 564,574 **** TraceTime timer("compilation policy safepoint handler", TRACETIME_LOG(Info, safepoint, cleanup)); CompilationPolicy::policy()->do_safepoint_work(); event_safepoint_cleanup_task_commit(event, name); } ! { const char* name = "mark nmethods"; EventSafepointCleanupTask event; TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); NMethodSweeper::mark_active_nmethods(); event_safepoint_cleanup_task_commit(event, name); --- 579,589 ---- TraceTime timer("compilation policy safepoint handler", TRACETIME_LOG(Info, safepoint, cleanup)); CompilationPolicy::policy()->do_safepoint_work(); event_safepoint_cleanup_task_commit(event, name); } ! if (op == NULL || ! op->marks_nmethods()) { const char* name = "mark nmethods"; EventSafepointCleanupTask event; TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); NMethodSweeper::mark_active_nmethods(); event_safepoint_cleanup_task_commit(event, name);
*** 599,608 **** --- 614,721 ---- ClassLoaderDataGraph::purge_if_needed(); event_safepoint_cleanup_task_commit(event, name); } } + class ParallelSPCleanupThreadClosure : public ThreadClosure { + private: + bool _do_deflate_idle_monitors; + CodeBlobClosure* _nmethod_cl; + + public: + ParallelSPCleanupThreadClosure() { + VM_Operation* op = VMThread::vm_operation(); + _do_deflate_idle_monitors = op == NULL || ! op->deflates_idle_monitors(); + if (op == NULL || ! op->marks_nmethods()) { + _nmethod_cl = NMethodSweeper::prepare_mark_active_nmethods(); + } else { + _nmethod_cl = NULL; + } + } + + void do_thread(Thread* thread) { + if (_do_deflate_idle_monitors) { + ObjectSynchronizer::deflate_idle_monitors_and_oops_do(thread, NULL); + } + if (_nmethod_cl != NULL) { + if (thread->is_Java_thread()) { + JavaThread* jt = (JavaThread*) thread; + if(! jt->is_Code_cache_sweeper_thread()) { + jt->nmethods_do(_nmethod_cl); + } + } + } + } + }; + + class ParallelSPCleanupTask : public AbstractGangTask { + private: + SubTasksDone _subtasks; + public: + ParallelSPCleanupTask() : + AbstractGangTask("Parallel Safepoint Cleanup"), + _subtasks(SafepointSynchronize::SAFEPOINT_CLEANUP_NUM_TASKS) {} + + void work(uint worker_id) { + // All threads deflate monitors and mark nmethods (if necessary). + ParallelSPCleanupThreadClosure cleanup_threads_cl; + Threads::parallel_java_threads_do(&cleanup_threads_cl); + + if (! _subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_DEFLATE_MONITORS)) { + const char* name = "deflating idle monitors"; + EventSafepointCleanupTask event; + TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); + ObjectSynchronizer::deflate_idle_monitors(false); + event_safepoint_cleanup_task_commit(event, name); + } + if (! _subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_UPDATE_INLINE_CACHES)) { + const char* name = "updating inline caches"; + EventSafepointCleanupTask event; + TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); + InlineCacheBuffer::update_inline_caches(); + event_safepoint_cleanup_task_commit(event, name); + } + + if (! _subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_SYMBOL_TABLE_REHASH)) { + const char* name = "rehashing symbol table"; + EventSafepointCleanupTask event; + TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); + SymbolTable::rehash_table(); + event_safepoint_cleanup_task_commit(event, name); + } + + if (! _subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_STRING_TABLE_REHASH)) { + const char* name = "rehashing string table"; + EventSafepointCleanupTask event; + TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); + StringTable::rehash_table(); + event_safepoint_cleanup_task_commit(event, name); + } + + if (! _subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_CLD_PURGE)) { + // CMS delays purging the CLDG until the beginning of the next safepoint and to + // make sure concurrent sweep is done + const char* name = "purging class loader data graph"; + EventSafepointCleanupTask event; + TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); + ClassLoaderDataGraph::purge_if_needed(); + event_safepoint_cleanup_task_commit(event, name); + } + } + }; + + void SafepointSynchronize::parallel_cleanup() { + // Deferred init + if (_cleanup_workers == NULL) { + _cleanup_workers = new WorkGang("Parallel Safepoint Cleanup", ParallelSPCleanupThreads, false, false); + _cleanup_workers->initialize_workers(); + } + + StrongRootsScope srs(_cleanup_workers->active_workers()); + ParallelSPCleanupTask cleanup_task; + _cleanup_workers->run_task(&cleanup_task); + } bool SafepointSynchronize::safepoint_safe(JavaThread *thread, JavaThreadState state) { switch(state) { case _thread_in_native: // native threads are safe if they have no java stack or have walkable stack
< prev index next >