void IdealGraphPrinter::clean_up() { JavaThread *p; for (p = Threads::first(); p; p = p->next()) { if (p->is_Compiler_thread()) { CompilerThread *c = (CompilerThread *)p; IdealGraphPrinter *printer = c->ideal_graph_printer(); if (printer) { delete printer; } c->set_ideal_graph_printer(NULL); } } }
int VM_Exit::wait_for_threads_in_native_to_block() { // VM exits at safepoint. This function must be called at the final safepoint // to wait for threads in _thread_in_native state to be quiescent. assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already"); Thread * thr_cur = Thread::current(); Monitor timer(Mutex::leaf, "VM_Exit timer", true, Monitor::_safepoint_check_never); // Compiler threads need longer wait because they can access VM data directly // while in native. If they are active and some structures being used are // deleted by the shutdown sequence, they will crash. On the other hand, user // threads must go through native=>Java/VM transitions first to access VM // data, and they will be stopped during state transition. In theory, we // don't have to wait for user threads to be quiescent, but it's always // better to terminate VM when current thread is the only active thread, so // wait for user threads too. Numbers are in 10 milliseconds. int max_wait_user_thread = 30; // at least 300 milliseconds int max_wait_compiler_thread = 1000; // at least 10 seconds int max_wait = max_wait_compiler_thread; int attempts = 0; while (true) { int num_active = 0; int num_active_compiler_thread = 0; for(JavaThread *thr = Threads::first(); thr != NULL; thr = thr->next()) { if (thr!=thr_cur && thr->thread_state() == _thread_in_native) { num_active++; if (thr->is_Compiler_thread()) { num_active_compiler_thread++; } } } if (num_active == 0) { return 0; } else if (attempts > max_wait) { return num_active; } else if (num_active_compiler_thread == 0 && attempts > max_wait_user_thread) { return num_active; } attempts++; MutexLockerEx ml(&timer, Mutex::_no_safepoint_check_flag); timer.wait(Mutex::_no_safepoint_check_flag, 10); } }
IdealGraphPrinter *IdealGraphPrinter::printer() { if (PrintIdealGraphLevel == 0) return NULL; JavaThread *thread = JavaThread::current(); if (!thread->is_Compiler_thread()) return NULL; CompilerThread *compiler_thread = (CompilerThread *)thread; if (compiler_thread->ideal_graph_printer() == NULL) { IdealGraphPrinter *printer = new IdealGraphPrinter(); compiler_thread->set_ideal_graph_printer(printer); } return compiler_thread->ideal_graph_printer(); }
void FlatProfiler::record_thread_ticks() { int maxthreads, suspendedthreadcount; JavaThread** threadsList; bool interval_expired = false; if (ProfileIntervals && (FlatProfiler::received_ticks >= interval_ticks_previous + ProfileIntervalsTicks)) { interval_expired = true; interval_ticks_previous = FlatProfiler::received_ticks; } // Try not to wait for the Threads_lock if (Threads_lock->try_lock()) { { // Threads_lock scope maxthreads = Threads::number_of_threads(); threadsList = NEW_C_HEAP_ARRAY(JavaThread *, maxthreads, mtInternal); suspendedthreadcount = 0; for (JavaThread* tp = Threads::first(); tp != NULL; tp = tp->next()) { if (tp->is_Compiler_thread()) { // Only record ticks for active compiler threads CompilerThread* cthread = (CompilerThread*)tp; if (cthread->task() != NULL) { // The compiler is active. If we need to access any of the fields // of the compiler task we should suspend the CompilerThread first. FlatProfiler::compiler_ticks += 1; continue; } } // First externally suspend all threads by marking each for // external suspension - so it will stop at its next transition // Then do a safepoint ThreadProfiler* pp = tp->get_thread_profiler(); if (pp != NULL && pp->engaged) { MutexLockerEx ml(tp->SR_lock(), Mutex::_no_safepoint_check_flag); if (!tp->is_external_suspend() && !tp->is_exiting()) { tp->set_external_suspend(); threadsList[suspendedthreadcount++] = tp; } } } Threads_lock->unlock(); }
JavaCallWrapper::JavaCallWrapper(methodHandle callee_method, Handle receiver, JavaValue* result, TRAPS) { JavaThread* thread = (JavaThread *)THREAD; bool clear_pending_exception = true; guarantee(thread->is_Java_thread(), "crucial check - the VM thread cannot and must not escape to Java code"); assert(!thread->owns_locks(), "must release all locks when leaving VM"); guarantee(!thread->is_Compiler_thread(), "cannot make java calls from the compiler"); _result = result; // Allocate handle block for Java code. This must be done before we change thread_state to _thread_in_Java_or_stub, // since it can potentially block. JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread); // After this, we are official in JavaCode. This needs to be done before we change any of the thread local // info, since we cannot find oops before the new information is set up completely. ThreadStateTransition::transition(thread, _thread_in_vm, _thread_in_Java); // Make sure that we handle asynchronous stops and suspends _before_ we clear all thread state // in JavaCallWrapper::JavaCallWrapper(). This way, we can decide if we need to do any pd actions // to prepare for stop/suspend (flush register windows on sparcs, cache sp, or other state). if (thread->has_special_runtime_exit_condition()) { thread->handle_special_runtime_exit_condition(); if (HAS_PENDING_EXCEPTION) { clear_pending_exception = false; } } // Make sure to set the oop's after the thread transition - since we can block there. No one is GC'ing // the JavaCallWrapper before the entry frame is on the stack. _callee_method = callee_method(); _receiver = receiver(); #ifdef CHECK_UNHANDLED_OOPS THREAD->allow_unhandled_oop(&_receiver); #endif // CHECK_UNHANDLED_OOPS _thread = (JavaThread *)thread; _handles = _thread->active_handles(); // save previous handle block & Java frame linkage // For the profiler, the last_Java_frame information in thread must always be in // legal state. We have no last Java frame if last_Java_sp == NULL so // the valid transition is to clear _last_Java_sp and then reset the rest of // the (platform specific) state. _anchor.copy(_thread->frame_anchor()); _thread->frame_anchor()->clear(); debug_only(_thread->inc_java_call_counter()); _thread->set_active_handles(new_handles); // install new handle block and reset Java frame linkage assert (_thread->thread_state() != _thread_in_native, "cannot set native pc to NULL"); // clear any pending exception in thread (native calls start with no exception pending) if(clear_pending_exception) { _thread->clear_pending_exception(); } if (_anchor.last_Java_sp() == NULL) { _thread->record_base_of_stack_pointer(); } }