< prev index next >

src/hotspot/share/services/threadService.cpp

Print this page
rev 47794 : Port 09.17.Thread_SMR_logging_update from JDK9 to JDK10
rev 47795 : sspitsyn, dcubed, eosterlund CR - minor changes prior to OpenJDK review.
rev 47796 : eosterlund, stefank CR - refactor code into threadSMR.cpp and threadSMR.hpp
rev 47797 : eosterlund CR - need more inline fixes.
rev 47798 : eosterlund, stefank CR - more inline and style cleanups
rev 47799 : stefank, coleenp CR - refactor most JavaThreadIterator usage to use JavaThreadIteratorWithHandle.

*** 32,44 **** #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" #include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/init.hpp" - #include "runtime/thread.hpp" - #include "runtime/vframe.hpp" #include "runtime/thread.inline.hpp" #include "runtime/vmThread.hpp" #include "runtime/vm_operations.hpp" #include "services/threadService.hpp" // TODO: we need to define a naming convention for perf counters --- 32,44 ---- #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" #include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/init.hpp" #include "runtime/thread.inline.hpp" + #include "runtime/threadSMR.inline.hpp" + #include "runtime/vframe.hpp" #include "runtime/vmThread.hpp" #include "runtime/vm_operations.hpp" #include "services/threadService.hpp" // TODO: we need to define a naming convention for perf counters
*** 146,156 **** } // FIXME: JVMTI should call this function Handle ThreadService::get_current_contended_monitor(JavaThread* thread) { assert(thread != NULL, "should be non-NULL"); ! assert(Threads_lock->owned_by_self(), "must grab Threads_lock or be at safepoint"); ObjectMonitor *wait_obj = thread->current_waiting_monitor(); oop obj = NULL; if (wait_obj != NULL) { --- 146,156 ---- } // FIXME: JVMTI should call this function Handle ThreadService::get_current_contended_monitor(JavaThread* thread) { assert(thread != NULL, "should be non-NULL"); ! debug_only(Thread::check_for_dangling_thread_pointer(thread);) ObjectMonitor *wait_obj = thread->current_waiting_monitor(); oop obj = NULL; if (wait_obj != NULL) {
*** 264,273 **** --- 264,274 ---- objArrayOop r = oopFactory::new_objArray(ik, num_threads, CHECK_NH); objArrayHandle result_obj(THREAD, r); int num_snapshots = dump_result.num_snapshots(); assert(num_snapshots == num_threads, "Must have num_threads thread snapshots"); + assert(num_snapshots == 0 || dump_result.t_list_has_been_set(), "ThreadsList must have been set if we have a snapshot"); int i = 0; for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; i++, ts = ts->next()) { ThreadStackTrace* stacktrace = ts->get_stack_trace(); if (stacktrace == NULL) { // No stack trace
*** 295,322 **** stat->reset_time_stat(); } } // Find deadlocks involving object monitors and concurrent locks if concurrent_locks is true ! DeadlockCycle* ThreadService::find_deadlocks_at_safepoint(bool concurrent_locks) { // This code was modified from the original Threads::find_deadlocks code. int globalDfn = 0, thisDfn; ObjectMonitor* waitingToLockMonitor = NULL; oop waitingToLockBlocker = NULL; bool blocked_on_monitor = false; JavaThread *currentThread, *previousThread; int num_deadlocks = 0; ! for (JavaThread* p = Threads::first(); p != NULL; p = p->next()) { ! // Initialize the depth-first-number ! p->set_depth_first_number(-1); } DeadlockCycle* deadlocks = NULL; DeadlockCycle* last = NULL; DeadlockCycle* cycle = new DeadlockCycle(); ! for (JavaThread* jt = Threads::first(); jt != NULL; jt = jt->next()) { if (jt->depth_first_number() >= 0) { // this thread was already visited continue; } --- 296,326 ---- stat->reset_time_stat(); } } // Find deadlocks involving object monitors and concurrent locks if concurrent_locks is true ! DeadlockCycle* ThreadService::find_deadlocks_at_safepoint(ThreadsList * t_list, bool concurrent_locks) { ! assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); ! // This code was modified from the original Threads::find_deadlocks code. int globalDfn = 0, thisDfn; ObjectMonitor* waitingToLockMonitor = NULL; oop waitingToLockBlocker = NULL; bool blocked_on_monitor = false; JavaThread *currentThread, *previousThread; int num_deadlocks = 0; ! // Initialize the depth-first-number for each JavaThread. ! JavaThreadIterator jti(t_list); ! for (JavaThread* jt = jti.first(); jt != NULL; jt = jti.next()) { ! jt->set_depth_first_number(-1); } DeadlockCycle* deadlocks = NULL; DeadlockCycle* last = NULL; DeadlockCycle* cycle = new DeadlockCycle(); ! for (JavaThread* jt = jti.first(); jt != NULL; jt = jti.next()) { if (jt->depth_first_number() >= 0) { // this thread was already visited continue; }
*** 337,349 **** while (waitingToLockMonitor != NULL || waitingToLockBlocker != NULL) { cycle->add_thread(currentThread); if (waitingToLockMonitor != NULL) { address currentOwner = (address)waitingToLockMonitor->owner(); if (currentOwner != NULL) { ! currentThread = Threads::owning_thread_from_monitor_owner( ! currentOwner, ! false /* no locking needed */); if (currentThread == NULL) { // This function is called at a safepoint so the JavaThread // that owns waitingToLockMonitor should be findable, but // if it is not findable, then the previous currentThread is // blocked permanently. We record this as a deadlock. --- 341,352 ---- while (waitingToLockMonitor != NULL || waitingToLockBlocker != NULL) { cycle->add_thread(currentThread); if (waitingToLockMonitor != NULL) { address currentOwner = (address)waitingToLockMonitor->owner(); if (currentOwner != NULL) { ! currentThread = Threads::owning_thread_from_monitor_owner(t_list, ! currentOwner); if (currentThread == NULL) { // This function is called at a safepoint so the JavaThread // that owns waitingToLockMonitor should be findable, but // if it is not findable, then the previous currentThread is // blocked permanently. We record this as a deadlock.
*** 364,373 **** --- 367,378 ---- } } else { if (concurrent_locks) { if (waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass())) { oop threadObj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(waitingToLockBlocker); + // This JavaThread (if there is one) is protected by the + // ThreadsListSetter in VM_FindDeadlocks::doit(). currentThread = threadObj != NULL ? java_lang_Thread::thread(threadObj) : NULL; } else { currentThread = NULL; } }
*** 412,430 **** } delete cycle; return deadlocks; } ! ThreadDumpResult::ThreadDumpResult() : _num_threads(0), _num_snapshots(0), _snapshots(NULL), _next(NULL), _last(NULL) { // Create a new ThreadDumpResult object and append to the list. // If GC happens before this function returns, Method* // in the stack trace will be visited. ThreadService::add_thread_dump(this); } ! ThreadDumpResult::ThreadDumpResult(int num_threads) : _num_threads(num_threads), _num_snapshots(0), _snapshots(NULL), _next(NULL), _last(NULL) { // Create a new ThreadDumpResult object and append to the list. // If GC happens before this function returns, oops // will be visited. ThreadService::add_thread_dump(this); } --- 417,435 ---- } delete cycle; return deadlocks; } ! ThreadDumpResult::ThreadDumpResult() : _num_threads(0), _num_snapshots(0), _snapshots(NULL), _next(NULL), _last(NULL), _setter() { // Create a new ThreadDumpResult object and append to the list. // If GC happens before this function returns, Method* // in the stack trace will be visited. ThreadService::add_thread_dump(this); } ! ThreadDumpResult::ThreadDumpResult(int num_threads) : _num_threads(num_threads), _num_snapshots(0), _snapshots(NULL), _next(NULL), _last(NULL), _setter() { // Create a new ThreadDumpResult object and append to the list. // If GC happens before this function returns, oops // will be visited. ThreadService::add_thread_dump(this); }
*** 465,474 **** --- 470,483 ---- for (ThreadSnapshot* ts = _snapshots; ts != NULL; ts = ts->next()) { ts->metadata_do(f); } } + ThreadsList* ThreadDumpResult::t_list() { + return _setter.list(); + } + StackFrameInfo::StackFrameInfo(javaVFrame* jvf, bool with_lock_info) { _method = jvf->method(); _bci = jvf->bci(); _class_holder = _method->method_holder()->klass_holder(); _locked_monitors = NULL;
*** 681,690 **** --- 690,701 ---- int length = aos_objects->length(); for (int i = 0; i < length; i++) { oop o = aos_objects->at(i); oop owner_thread_obj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(o); if (owner_thread_obj != NULL) { + // See comments in ThreadConcurrentLocks to see how this + // JavaThread* is protected. JavaThread* thread = java_lang_Thread::thread(owner_thread_obj); assert(o->is_instance(), "Must be an instanceOop"); add_lock(thread, (instanceOop) o); } }
*** 762,772 **** _count_pending_reset = false; _timer_pending_reset = false; memset((void*) _perf_recursion_counts, 0, sizeof(_perf_recursion_counts)); } ! ThreadSnapshot::ThreadSnapshot(JavaThread* thread) { _thread = thread; _threadObj = thread->threadObj(); _stack_trace = NULL; _concurrent_locks = NULL; _next = NULL; --- 773,783 ---- _count_pending_reset = false; _timer_pending_reset = false; memset((void*) _perf_recursion_counts, 0, sizeof(_perf_recursion_counts)); } ! ThreadSnapshot::ThreadSnapshot(ThreadsList * t_list, JavaThread* thread) { _thread = thread; _threadObj = thread->threadObj(); _stack_trace = NULL; _concurrent_locks = NULL; _next = NULL;
*** 794,804 **** if (obj() == NULL) { // monitor no longer exists; thread is not blocked _thread_status = java_lang_Thread::RUNNABLE; } else { _blocker_object = obj(); ! JavaThread* owner = ObjectSynchronizer::get_lock_owner(obj, false); if ((owner == NULL && _thread_status == java_lang_Thread::BLOCKED_ON_MONITOR_ENTER) || (owner != NULL && owner->is_attaching_via_jni())) { // ownership information of the monitor is not available // (may no longer be owned or releasing to some other thread) // make this thread in RUNNABLE state. --- 805,815 ---- if (obj() == NULL) { // monitor no longer exists; thread is not blocked _thread_status = java_lang_Thread::RUNNABLE; } else { _blocker_object = obj(); ! JavaThread* owner = ObjectSynchronizer::get_lock_owner(t_list, obj); if ((owner == NULL && _thread_status == java_lang_Thread::BLOCKED_ON_MONITOR_ENTER) || (owner != NULL && owner->is_attaching_via_jni())) { // ownership information of the monitor is not available // (may no longer be owned or releasing to some other thread) // make this thread in RUNNABLE state.
*** 863,873 **** DeadlockCycle::~DeadlockCycle() { delete _threads; } ! void DeadlockCycle::print_on(outputStream* st) const { st->cr(); st->print_cr("Found one Java-level deadlock:"); st->print("============================="); JavaThread* currentThread; --- 874,884 ---- DeadlockCycle::~DeadlockCycle() { delete _threads; } ! void DeadlockCycle::print_on_with(ThreadsList * t_list, outputStream* st) const { st->cr(); st->print_cr("Found one Java-level deadlock:"); st->print("============================="); JavaThread* currentThread;
*** 893,905 **** } } else { // No Java object associated - a JVMTI raw monitor owner_desc = " (JVMTI raw monitor),\n which is held by"; } ! currentThread = Threads::owning_thread_from_monitor_owner( ! (address)waitingToLockMonitor->owner(), ! false /* no locking needed */); if (currentThread == NULL) { // The deadlock was detected at a safepoint so the JavaThread // that owns waitingToLockMonitor should be findable, but // if it is not findable, then the previous currentThread is // blocked permanently. --- 904,915 ---- } } else { // No Java object associated - a JVMTI raw monitor owner_desc = " (JVMTI raw monitor),\n which is held by"; } ! currentThread = Threads::owning_thread_from_monitor_owner(t_list, ! (address)waitingToLockMonitor->owner()); if (currentThread == NULL) { // The deadlock was detected at a safepoint so the JavaThread // that owns waitingToLockMonitor should be findable, but // if it is not findable, then the previous currentThread is // blocked permanently.
*** 913,922 **** --- 923,933 ---- waitingToLockBlocker->klass()->external_name()); assert(waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass()), "Must be an AbstractOwnableSynchronizer"); oop ownerObj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(waitingToLockBlocker); currentThread = java_lang_Thread::thread(ownerObj); + assert(currentThread != NULL, "AbstractOwnableSynchronizer owning thread is unexpectedly NULL"); } st->print("%s \"%s\"", owner_desc, currentThread->get_thread_name()); } st->cr();
*** 941,953 **** assert(cur_thread == Thread::current(), "Check current thread"); int init_size = ThreadService::get_live_thread_count(); _threads_array = new GrowableArray<instanceHandle>(init_size); ! MutexLockerEx ml(Threads_lock); ! ! for (JavaThread* jt = Threads::first(); jt != NULL; jt = jt->next()) { // skips JavaThreads in the process of exiting // and also skips VM internal JavaThreads // Threads in _thread_new or _thread_new_trans state are included. // i.e. threads have been started but not yet running. if (jt->threadObj() == NULL || --- 952,962 ---- assert(cur_thread == Thread::current(), "Check current thread"); int init_size = ThreadService::get_live_thread_count(); _threads_array = new GrowableArray<instanceHandle>(init_size); ! for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) { // skips JavaThreads in the process of exiting // and also skips VM internal JavaThreads // Threads in _thread_new or _thread_new_trans state are included. // i.e. threads have been started but not yet running. if (jt->threadObj() == NULL ||
< prev index next >