< prev index next >

src/share/vm/runtime/safepoint.cpp

Print this page
rev 13047 : [mq]: 8180932.patch

*** 69,78 **** --- 69,82 ---- #endif // -------------------------------------------------------------------------------------------------- // Implementation of Safepoint begin/end + WorkGang* SafepointSynchronize::_cleanup_workers = NULL; + SubTasksDone* SafepointSynchronize::_cleanup_subtasks = NULL; + uint SafepointSynchronize::_num_cleanup_workers = 0; + 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;
*** 536,605 **** event.set_name(name); event.commit(); } } ! // 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"; EventSafepointCleanupTask event; TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); InlineCacheBuffer::update_inline_caches(); event_safepoint_cleanup_task_commit(event, name); } ! { const char* name = "compilation policy safepoint handler"; EventSafepointCleanupTask event; 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); ! } ! if (SymbolTable::needs_rehashing()) { 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 (StringTable::needs_rehashing()) { 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); } ! { // 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); } ! } 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 --- 540,673 ---- event.set_name(name); event.commit(); } } ! class ParallelSPCleanupThreadClosure : public ThreadClosure { ! private: ! CodeBlobClosure* _nmethod_cl; ! ! public: ! ParallelSPCleanupThreadClosure() { ! _nmethod_cl = NMethodSweeper::prepare_mark_active_nmethods(); ! } ! ! void do_thread(Thread* thread) { ! ObjectSynchronizer::deflate_thread_local_monitors(thread); ! if (_nmethod_cl != NULL && thread->is_Java_thread() && ! ! thread->is_Code_cache_sweeper_thread()) { ! JavaThread* jt = (JavaThread*) thread; ! jt->nmethods_do(_nmethod_cl); ! } ! } ! }; ! ! class ParallelSPCleanupTask : public AbstractGangTask { ! private: ! SubTasksDone* _subtasks; ! ParallelSPCleanupThreadClosure _cleanup_threads_cl; ! public: ! ParallelSPCleanupTask(SubTasksDone* subtasks) : ! AbstractGangTask("Parallel Safepoint Cleanup"), ! _cleanup_threads_cl(ParallelSPCleanupThreadClosure()), ! _subtasks(subtasks) {} ! ! void work(uint worker_id) { ! // All threads deflate monitors and mark nmethods (if necessary). ! 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(); 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_COMPILATION_POLICY)) { const char* name = "compilation policy safepoint handler"; EventSafepointCleanupTask event; TraceTime timer("compilation policy safepoint handler", TRACETIME_LOG(Info, safepoint, cleanup)); CompilationPolicy::policy()->do_safepoint_work(); event_safepoint_cleanup_task_commit(event, name); } ! if (! _subtasks->is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_SYMBOL_TABLE_REHASH)) { if (SymbolTable::needs_rehashing()) { 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)) { if (StringTable::needs_rehashing()) { 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); } ! _subtasks->all_tasks_completed(SafepointSynchronize::_num_cleanup_workers); ! } ! }; ! ! // Various cleaning tasks that should be done periodically at safepoints ! void SafepointSynchronize::do_cleanup_tasks() { ! if (_num_cleanup_workers == 0) { ! // Deferred initialization. ! if (ParallelSafepointCleanup) { ! assert(_cleanup_workers == NULL, "already initialized?"); ! // Ask the GC to share its workers. ! CollectedHeap* heap = Universe::heap(); ! assert(heap != NULL, "heap not initialized yet?"); ! _cleanup_workers = heap->get_safepoint_workers(); ! if (_cleanup_workers == NULL) { ! // If GC doesn't want to share or doesn't even use worker threads, we create our own thread pool. ! _cleanup_workers = new WorkGang("Parallel Safepoint Cleanup", ParallelSafepointCleanupThreads, false, false); ! _cleanup_workers->initialize_workers(); ! } ! _num_cleanup_workers = MIN2(ParallelSafepointCleanupThreads, _cleanup_workers->total_workers()); ! } else { ! _num_cleanup_workers = 1; ! } ! assert(_num_cleanup_workers != 0, "not initialized?"); ! _cleanup_subtasks = new SubTasksDone(SAFEPOINT_CLEANUP_NUM_TASKS); ! } + // Run cleanup serially or in parallel. + ParallelSPCleanupTask cleanup(_cleanup_subtasks); + StrongRootsScope srs(_num_cleanup_workers); + if (ParallelSafepointCleanup) { + assert(_cleanup_workers != NULL, "no cleanup workers?"); + _cleanup_workers->run_task(&cleanup, _num_cleanup_workers); + } else { + assert(_num_cleanup_workers == 1, "only 1 thread"); + cleanup.work(0); + } + } 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 >