< prev index next >
src/hotspot/share/services/threadService.cpp
Print this page
rev 47674 : Port 09.17.Thread_SMR_logging_update from JDK9 to JDK10
rev 47675 : sspitsyn, dcubed, eosterlund CR - minor changes prior to OpenJDK review.
rev 47676 : eosterlund, stefank CR - refactor code into threadSMR.cpp and threadSMR.hpp
rev 47677 : eosterlund CR - need more inline fixes.
rev 47678 : eosterlund, stefank CR - more inline and style cleanups
rev 47679 : 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 >