annotate src/share/vm/services/threadService.cpp @ 1721:413ad0331a0c

6977924: Changes for 6975078 produce build error with certain gcc versions Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error. Reviewed-by: jcoomes, ysr, phh
author johnc
date Wed, 18 Aug 2010 10:59:06 -0700
parents c18cbe5936b8
children f95d63e2154a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1142
diff changeset
2 * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1142
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1142
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1142
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 # include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 # include "incls/_threadService.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 // TODO: we need to define a naming convention for perf counters
a61af66fc99e Initial load
duke
parents:
diff changeset
29 // to distinguish counters for:
a61af66fc99e Initial load
duke
parents:
diff changeset
30 // - standard JSR174 use
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // - Hotspot extension (public and committed)
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // - Hotspot extension (private/internal and uncommitted)
a61af66fc99e Initial load
duke
parents:
diff changeset
33
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // Default is disabled.
a61af66fc99e Initial load
duke
parents:
diff changeset
35 bool ThreadService::_thread_monitoring_contention_enabled = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
36 bool ThreadService::_thread_cpu_time_enabled = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 PerfCounter* ThreadService::_total_threads_count = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
39 PerfVariable* ThreadService::_live_threads_count = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 PerfVariable* ThreadService::_peak_threads_count = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 PerfVariable* ThreadService::_daemon_threads_count = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
42 volatile int ThreadService::_exiting_threads_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
43 volatile int ThreadService::_exiting_daemon_threads_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
44
a61af66fc99e Initial load
duke
parents:
diff changeset
45 ThreadDumpResult* ThreadService::_threaddump_list = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 static const int INITIAL_ARRAY_SIZE = 10;
a61af66fc99e Initial load
duke
parents:
diff changeset
48
a61af66fc99e Initial load
duke
parents:
diff changeset
49 void ThreadService::init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
50 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 // These counters are for java.lang.management API support.
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // They are created even if -XX:-UsePerfData is set and in
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // that case, they will be allocated on C heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
55
a61af66fc99e Initial load
duke
parents:
diff changeset
56 _total_threads_count =
a61af66fc99e Initial load
duke
parents:
diff changeset
57 PerfDataManager::create_counter(JAVA_THREADS, "started",
a61af66fc99e Initial load
duke
parents:
diff changeset
58 PerfData::U_Events, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
59
a61af66fc99e Initial load
duke
parents:
diff changeset
60 _live_threads_count =
a61af66fc99e Initial load
duke
parents:
diff changeset
61 PerfDataManager::create_variable(JAVA_THREADS, "live",
a61af66fc99e Initial load
duke
parents:
diff changeset
62 PerfData::U_None, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
63
a61af66fc99e Initial load
duke
parents:
diff changeset
64 _peak_threads_count =
a61af66fc99e Initial load
duke
parents:
diff changeset
65 PerfDataManager::create_variable(JAVA_THREADS, "livePeak",
a61af66fc99e Initial load
duke
parents:
diff changeset
66 PerfData::U_None, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68 _daemon_threads_count =
a61af66fc99e Initial load
duke
parents:
diff changeset
69 PerfDataManager::create_variable(JAVA_THREADS, "daemon",
a61af66fc99e Initial load
duke
parents:
diff changeset
70 PerfData::U_None, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
71
a61af66fc99e Initial load
duke
parents:
diff changeset
72 if (os::is_thread_cpu_time_supported()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
73 _thread_cpu_time_enabled = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
74 }
a61af66fc99e Initial load
duke
parents:
diff changeset
75 }
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 void ThreadService::reset_peak_thread_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // Acquire the lock to update the peak thread count
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // to synchronize with thread addition and removal.
a61af66fc99e Initial load
duke
parents:
diff changeset
80 MutexLockerEx mu(Threads_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
81 _peak_threads_count->set_value(get_live_thread_count());
a61af66fc99e Initial load
duke
parents:
diff changeset
82 }
a61af66fc99e Initial load
duke
parents:
diff changeset
83
a61af66fc99e Initial load
duke
parents:
diff changeset
84 void ThreadService::add_thread(JavaThread* thread, bool daemon) {
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // Do not count VM internal or JVMTI agent threads
a61af66fc99e Initial load
duke
parents:
diff changeset
86 if (thread->is_hidden_from_external_view() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
87 thread->is_jvmti_agent_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
88 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
89 }
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 _total_threads_count->inc();
a61af66fc99e Initial load
duke
parents:
diff changeset
92 _live_threads_count->inc();
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94 if (_live_threads_count->get_value() > _peak_threads_count->get_value()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
95 _peak_threads_count->set_value(_live_threads_count->get_value());
a61af66fc99e Initial load
duke
parents:
diff changeset
96 }
a61af66fc99e Initial load
duke
parents:
diff changeset
97
a61af66fc99e Initial load
duke
parents:
diff changeset
98 if (daemon) {
a61af66fc99e Initial load
duke
parents:
diff changeset
99 _daemon_threads_count->inc();
a61af66fc99e Initial load
duke
parents:
diff changeset
100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
102
a61af66fc99e Initial load
duke
parents:
diff changeset
103 void ThreadService::remove_thread(JavaThread* thread, bool daemon) {
a61af66fc99e Initial load
duke
parents:
diff changeset
104 Atomic::dec((jint*) &_exiting_threads_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 if (thread->is_hidden_from_external_view() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
107 thread->is_jvmti_agent_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
110
a61af66fc99e Initial load
duke
parents:
diff changeset
111 _live_threads_count->set_value(_live_threads_count->get_value() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
112
a61af66fc99e Initial load
duke
parents:
diff changeset
113 if (daemon) {
a61af66fc99e Initial load
duke
parents:
diff changeset
114 _daemon_threads_count->set_value(_daemon_threads_count->get_value() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
115 Atomic::dec((jint*) &_exiting_daemon_threads_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
118
a61af66fc99e Initial load
duke
parents:
diff changeset
119 void ThreadService::current_thread_exiting(JavaThread* jt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
120 assert(jt == JavaThread::current(), "Called by current thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
121 Atomic::inc((jint*) &_exiting_threads_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
122
a61af66fc99e Initial load
duke
parents:
diff changeset
123 oop threadObj = jt->threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
124 if (threadObj != NULL && java_lang_Thread::is_daemon(threadObj)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
125 Atomic::inc((jint*) &_exiting_daemon_threads_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // FIXME: JVMTI should call this function
a61af66fc99e Initial load
duke
parents:
diff changeset
130 Handle ThreadService::get_current_contended_monitor(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
131 assert(thread != NULL, "should be non-NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
132 assert(Threads_lock->owned_by_self(), "must grab Threads_lock or be at safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
133
a61af66fc99e Initial load
duke
parents:
diff changeset
134 ObjectMonitor *wait_obj = thread->current_waiting_monitor();
a61af66fc99e Initial load
duke
parents:
diff changeset
135
a61af66fc99e Initial load
duke
parents:
diff changeset
136 oop obj = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
137 if (wait_obj != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
138 // thread is doing an Object.wait() call
a61af66fc99e Initial load
duke
parents:
diff changeset
139 obj = (oop) wait_obj->object();
a61af66fc99e Initial load
duke
parents:
diff changeset
140 assert(obj != NULL, "Object.wait() should have an object");
a61af66fc99e Initial load
duke
parents:
diff changeset
141 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
142 ObjectMonitor *enter_obj = thread->current_pending_monitor();
a61af66fc99e Initial load
duke
parents:
diff changeset
143 if (enter_obj != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // thread is trying to enter() or raw_enter() an ObjectMonitor.
a61af66fc99e Initial load
duke
parents:
diff changeset
145 obj = (oop) enter_obj->object();
a61af66fc99e Initial load
duke
parents:
diff changeset
146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // If obj == NULL, then ObjectMonitor is raw which doesn't count.
a61af66fc99e Initial load
duke
parents:
diff changeset
148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
149
a61af66fc99e Initial load
duke
parents:
diff changeset
150 Handle h(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
151 return h;
a61af66fc99e Initial load
duke
parents:
diff changeset
152 }
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154 bool ThreadService::set_thread_monitoring_contention(bool flag) {
a61af66fc99e Initial load
duke
parents:
diff changeset
155 MutexLocker m(Management_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157 bool prev = _thread_monitoring_contention_enabled;
a61af66fc99e Initial load
duke
parents:
diff changeset
158 _thread_monitoring_contention_enabled = flag;
a61af66fc99e Initial load
duke
parents:
diff changeset
159
a61af66fc99e Initial load
duke
parents:
diff changeset
160 return prev;
a61af66fc99e Initial load
duke
parents:
diff changeset
161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
162
a61af66fc99e Initial load
duke
parents:
diff changeset
163 bool ThreadService::set_thread_cpu_time_enabled(bool flag) {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 MutexLocker m(Management_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
165
a61af66fc99e Initial load
duke
parents:
diff changeset
166 bool prev = _thread_cpu_time_enabled;
a61af66fc99e Initial load
duke
parents:
diff changeset
167 _thread_cpu_time_enabled = flag;
a61af66fc99e Initial load
duke
parents:
diff changeset
168
a61af66fc99e Initial load
duke
parents:
diff changeset
169 return prev;
a61af66fc99e Initial load
duke
parents:
diff changeset
170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // GC support
a61af66fc99e Initial load
duke
parents:
diff changeset
173 void ThreadService::oops_do(OopClosure* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
174 for (ThreadDumpResult* dump = _threaddump_list; dump != NULL; dump = dump->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
175 dump->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
176 }
a61af66fc99e Initial load
duke
parents:
diff changeset
177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 void ThreadService::add_thread_dump(ThreadDumpResult* dump) {
a61af66fc99e Initial load
duke
parents:
diff changeset
180 MutexLocker ml(Management_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
181 if (_threaddump_list == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
182 _threaddump_list = dump;
a61af66fc99e Initial load
duke
parents:
diff changeset
183 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
184 dump->set_next(_threaddump_list);
a61af66fc99e Initial load
duke
parents:
diff changeset
185 _threaddump_list = dump;
a61af66fc99e Initial load
duke
parents:
diff changeset
186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189 void ThreadService::remove_thread_dump(ThreadDumpResult* dump) {
a61af66fc99e Initial load
duke
parents:
diff changeset
190 MutexLocker ml(Management_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
191
a61af66fc99e Initial load
duke
parents:
diff changeset
192 ThreadDumpResult* prev = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
193 bool found = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
194 for (ThreadDumpResult* d = _threaddump_list; d != NULL; prev = d, d = d->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 if (d == dump) {
a61af66fc99e Initial load
duke
parents:
diff changeset
196 if (prev == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
197 _threaddump_list = dump->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
198 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
199 prev->set_next(dump->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
201 found = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
202 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
205 assert(found, "The threaddump result to be removed must exist.");
a61af66fc99e Initial load
duke
parents:
diff changeset
206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 // Dump stack trace of threads specified in the given threads array.
a61af66fc99e Initial load
duke
parents:
diff changeset
209 // Returns StackTraceElement[][] each element is the stack trace of a thread in
a61af66fc99e Initial load
duke
parents:
diff changeset
210 // the corresponding entry in the given threads array
a61af66fc99e Initial load
duke
parents:
diff changeset
211 Handle ThreadService::dump_stack_traces(GrowableArray<instanceHandle>* threads,
a61af66fc99e Initial load
duke
parents:
diff changeset
212 int num_threads,
a61af66fc99e Initial load
duke
parents:
diff changeset
213 TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
214 assert(num_threads > 0, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
215
a61af66fc99e Initial load
duke
parents:
diff changeset
216 ThreadDumpResult dump_result;
a61af66fc99e Initial load
duke
parents:
diff changeset
217 VM_ThreadDump op(&dump_result,
a61af66fc99e Initial load
duke
parents:
diff changeset
218 threads,
a61af66fc99e Initial load
duke
parents:
diff changeset
219 num_threads,
a61af66fc99e Initial load
duke
parents:
diff changeset
220 -1, /* entire stack */
a61af66fc99e Initial load
duke
parents:
diff changeset
221 false, /* with locked monitors */
a61af66fc99e Initial load
duke
parents:
diff changeset
222 false /* with locked synchronizers */);
a61af66fc99e Initial load
duke
parents:
diff changeset
223 VMThread::execute(&op);
a61af66fc99e Initial load
duke
parents:
diff changeset
224
a61af66fc99e Initial load
duke
parents:
diff changeset
225 // Allocate the resulting StackTraceElement[][] object
a61af66fc99e Initial load
duke
parents:
diff changeset
226
a61af66fc99e Initial load
duke
parents:
diff changeset
227 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
228 klassOop k = SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_StackTraceElement_array(), true, CHECK_NH);
a61af66fc99e Initial load
duke
parents:
diff changeset
229 objArrayKlassHandle ik (THREAD, k);
a61af66fc99e Initial load
duke
parents:
diff changeset
230 objArrayOop r = oopFactory::new_objArray(ik(), num_threads, CHECK_NH);
a61af66fc99e Initial load
duke
parents:
diff changeset
231 objArrayHandle result_obj(THREAD, r);
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 int num_snapshots = dump_result.num_snapshots();
a61af66fc99e Initial load
duke
parents:
diff changeset
234 assert(num_snapshots == num_threads, "Must have num_threads thread snapshots");
a61af66fc99e Initial load
duke
parents:
diff changeset
235 int i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
236 for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; i++, ts = ts->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
237 ThreadStackTrace* stacktrace = ts->get_stack_trace();
a61af66fc99e Initial load
duke
parents:
diff changeset
238 if (stacktrace == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // No stack trace
a61af66fc99e Initial load
duke
parents:
diff changeset
240 result_obj->obj_at_put(i, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
241 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // Construct an array of java/lang/StackTraceElement object
a61af66fc99e Initial load
duke
parents:
diff changeset
243 Handle backtrace_h = stacktrace->allocate_fill_stack_trace_element_array(CHECK_NH);
a61af66fc99e Initial load
duke
parents:
diff changeset
244 result_obj->obj_at_put(i, backtrace_h());
a61af66fc99e Initial load
duke
parents:
diff changeset
245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
247
a61af66fc99e Initial load
duke
parents:
diff changeset
248 return result_obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
250
a61af66fc99e Initial load
duke
parents:
diff changeset
251 void ThreadService::reset_contention_count_stat(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
252 ThreadStatistics* stat = thread->get_thread_stat();
a61af66fc99e Initial load
duke
parents:
diff changeset
253 if (stat != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
254 stat->reset_count_stat();
a61af66fc99e Initial load
duke
parents:
diff changeset
255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
257
a61af66fc99e Initial load
duke
parents:
diff changeset
258 void ThreadService::reset_contention_time_stat(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
259 ThreadStatistics* stat = thread->get_thread_stat();
a61af66fc99e Initial load
duke
parents:
diff changeset
260 if (stat != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
261 stat->reset_time_stat();
a61af66fc99e Initial load
duke
parents:
diff changeset
262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
264
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // Find deadlocks involving object monitors and concurrent locks if concurrent_locks is true
a61af66fc99e Initial load
duke
parents:
diff changeset
266 DeadlockCycle* ThreadService::find_deadlocks_at_safepoint(bool concurrent_locks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // This code was modified from the original Threads::find_deadlocks code.
a61af66fc99e Initial load
duke
parents:
diff changeset
268 int globalDfn = 0, thisDfn;
a61af66fc99e Initial load
duke
parents:
diff changeset
269 ObjectMonitor* waitingToLockMonitor = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
270 oop waitingToLockBlocker = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
271 bool blocked_on_monitor = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
272 JavaThread *currentThread, *previousThread;
a61af66fc99e Initial load
duke
parents:
diff changeset
273 int num_deadlocks = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
274
a61af66fc99e Initial load
duke
parents:
diff changeset
275 for (JavaThread* p = Threads::first(); p != NULL; p = p->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
276 // Initialize the depth-first-number
a61af66fc99e Initial load
duke
parents:
diff changeset
277 p->set_depth_first_number(-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
279
a61af66fc99e Initial load
duke
parents:
diff changeset
280 DeadlockCycle* deadlocks = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
281 DeadlockCycle* last = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
282 DeadlockCycle* cycle = new DeadlockCycle();
a61af66fc99e Initial load
duke
parents:
diff changeset
283 for (JavaThread* jt = Threads::first(); jt != NULL; jt = jt->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
284 if (jt->depth_first_number() >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // this thread was already visited
a61af66fc99e Initial load
duke
parents:
diff changeset
286 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
288
a61af66fc99e Initial load
duke
parents:
diff changeset
289 thisDfn = globalDfn;
a61af66fc99e Initial load
duke
parents:
diff changeset
290 jt->set_depth_first_number(globalDfn++);
a61af66fc99e Initial load
duke
parents:
diff changeset
291 previousThread = jt;
a61af66fc99e Initial load
duke
parents:
diff changeset
292 currentThread = jt;
a61af66fc99e Initial load
duke
parents:
diff changeset
293
a61af66fc99e Initial load
duke
parents:
diff changeset
294 cycle->reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
295
a61af66fc99e Initial load
duke
parents:
diff changeset
296 // When there is a deadlock, all the monitors involved in the dependency
a61af66fc99e Initial load
duke
parents:
diff changeset
297 // cycle must be contended and heavyweight. So we only care about the
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // heavyweight monitor a thread is waiting to lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
299 waitingToLockMonitor = (ObjectMonitor*)jt->current_pending_monitor();
a61af66fc99e Initial load
duke
parents:
diff changeset
300 if (concurrent_locks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
301 waitingToLockBlocker = jt->current_park_blocker();
a61af66fc99e Initial load
duke
parents:
diff changeset
302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
303 while (waitingToLockMonitor != NULL || waitingToLockBlocker != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
304 cycle->add_thread(currentThread);
a61af66fc99e Initial load
duke
parents:
diff changeset
305 if (waitingToLockMonitor != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
306 currentThread = Threads::owning_thread_from_monitor_owner((address)waitingToLockMonitor->owner(),
a61af66fc99e Initial load
duke
parents:
diff changeset
307 false /* no locking needed */);
a61af66fc99e Initial load
duke
parents:
diff changeset
308 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
309 if (concurrent_locks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
310 if (waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
311 oop threadObj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(waitingToLockBlocker);
a61af66fc99e Initial load
duke
parents:
diff changeset
312 currentThread = threadObj != NULL ? java_lang_Thread::thread(threadObj) : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
313 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
314 currentThread = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
318
a61af66fc99e Initial load
duke
parents:
diff changeset
319 if (currentThread == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
320 // No dependency on another thread
a61af66fc99e Initial load
duke
parents:
diff changeset
321 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
323 if (currentThread->depth_first_number() < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // First visit to this thread
a61af66fc99e Initial load
duke
parents:
diff changeset
325 currentThread->set_depth_first_number(globalDfn++);
a61af66fc99e Initial load
duke
parents:
diff changeset
326 } else if (currentThread->depth_first_number() < thisDfn) {
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // Thread already visited, and not on a (new) cycle
a61af66fc99e Initial load
duke
parents:
diff changeset
328 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
329 } else if (currentThread == previousThread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // Self-loop, ignore
a61af66fc99e Initial load
duke
parents:
diff changeset
331 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
332 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // We have a (new) cycle
a61af66fc99e Initial load
duke
parents:
diff changeset
334 num_deadlocks++;
a61af66fc99e Initial load
duke
parents:
diff changeset
335
a61af66fc99e Initial load
duke
parents:
diff changeset
336 cycle->set_deadlock(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
337
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // add this cycle to the deadlocks list
a61af66fc99e Initial load
duke
parents:
diff changeset
339 if (deadlocks == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
340 deadlocks = cycle;
a61af66fc99e Initial load
duke
parents:
diff changeset
341 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
342 last->set_next(cycle);
a61af66fc99e Initial load
duke
parents:
diff changeset
343 }
a61af66fc99e Initial load
duke
parents:
diff changeset
344 last = cycle;
a61af66fc99e Initial load
duke
parents:
diff changeset
345 cycle = new DeadlockCycle();
a61af66fc99e Initial load
duke
parents:
diff changeset
346 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
348 previousThread = currentThread;
a61af66fc99e Initial load
duke
parents:
diff changeset
349 waitingToLockMonitor = (ObjectMonitor*)currentThread->current_pending_monitor();
a61af66fc99e Initial load
duke
parents:
diff changeset
350 if (concurrent_locks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
351 waitingToLockBlocker = currentThread->current_park_blocker();
a61af66fc99e Initial load
duke
parents:
diff changeset
352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
354
a61af66fc99e Initial load
duke
parents:
diff changeset
355 }
a61af66fc99e Initial load
duke
parents:
diff changeset
356
a61af66fc99e Initial load
duke
parents:
diff changeset
357 return deadlocks;
a61af66fc99e Initial load
duke
parents:
diff changeset
358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
359
a61af66fc99e Initial load
duke
parents:
diff changeset
360 ThreadDumpResult::ThreadDumpResult() : _num_threads(0), _num_snapshots(0), _snapshots(NULL), _next(NULL), _last(NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // Create a new ThreadDumpResult object and append to the list.
a61af66fc99e Initial load
duke
parents:
diff changeset
363 // If GC happens before this function returns, methodOop
a61af66fc99e Initial load
duke
parents:
diff changeset
364 // in the stack trace will be visited.
a61af66fc99e Initial load
duke
parents:
diff changeset
365 ThreadService::add_thread_dump(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
367
a61af66fc99e Initial load
duke
parents:
diff changeset
368 ThreadDumpResult::ThreadDumpResult(int num_threads) : _num_threads(num_threads), _num_snapshots(0), _snapshots(NULL), _next(NULL), _last(NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
369 // Create a new ThreadDumpResult object and append to the list.
a61af66fc99e Initial load
duke
parents:
diff changeset
370 // If GC happens before this function returns, oops
a61af66fc99e Initial load
duke
parents:
diff changeset
371 // will be visited.
a61af66fc99e Initial load
duke
parents:
diff changeset
372 ThreadService::add_thread_dump(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
374
a61af66fc99e Initial load
duke
parents:
diff changeset
375 ThreadDumpResult::~ThreadDumpResult() {
a61af66fc99e Initial load
duke
parents:
diff changeset
376 ThreadService::remove_thread_dump(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
377
a61af66fc99e Initial load
duke
parents:
diff changeset
378 // free all the ThreadSnapshot objects created during
a61af66fc99e Initial load
duke
parents:
diff changeset
379 // the VM_ThreadDump operation
a61af66fc99e Initial load
duke
parents:
diff changeset
380 ThreadSnapshot* ts = _snapshots;
a61af66fc99e Initial load
duke
parents:
diff changeset
381 while (ts != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
382 ThreadSnapshot* p = ts;
a61af66fc99e Initial load
duke
parents:
diff changeset
383 ts = ts->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
384 delete p;
a61af66fc99e Initial load
duke
parents:
diff changeset
385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
386 }
a61af66fc99e Initial load
duke
parents:
diff changeset
387
a61af66fc99e Initial load
duke
parents:
diff changeset
388
a61af66fc99e Initial load
duke
parents:
diff changeset
389 void ThreadDumpResult::add_thread_snapshot(ThreadSnapshot* ts) {
a61af66fc99e Initial load
duke
parents:
diff changeset
390 assert(_num_threads == 0 || _num_snapshots < _num_threads,
a61af66fc99e Initial load
duke
parents:
diff changeset
391 "_num_snapshots must be less than _num_threads");
a61af66fc99e Initial load
duke
parents:
diff changeset
392 _num_snapshots++;
a61af66fc99e Initial load
duke
parents:
diff changeset
393 if (_snapshots == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 _snapshots = ts;
a61af66fc99e Initial load
duke
parents:
diff changeset
395 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
396 _last->set_next(ts);
a61af66fc99e Initial load
duke
parents:
diff changeset
397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
398 _last = ts;
a61af66fc99e Initial load
duke
parents:
diff changeset
399 }
a61af66fc99e Initial load
duke
parents:
diff changeset
400
a61af66fc99e Initial load
duke
parents:
diff changeset
401 void ThreadDumpResult::oops_do(OopClosure* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
402 for (ThreadSnapshot* ts = _snapshots; ts != NULL; ts = ts->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
403 ts->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
406
a61af66fc99e Initial load
duke
parents:
diff changeset
407 StackFrameInfo::StackFrameInfo(javaVFrame* jvf, bool with_lock_info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
408 _method = jvf->method();
a61af66fc99e Initial load
duke
parents:
diff changeset
409 _bci = jvf->bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
410 _locked_monitors = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
411 if (with_lock_info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
412 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
413 GrowableArray<MonitorInfo*>* list = jvf->locked_monitors();
a61af66fc99e Initial load
duke
parents:
diff changeset
414 int length = list->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
415 if (length > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
416 _locked_monitors = new (ResourceObj::C_HEAP) GrowableArray<oop>(length, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
417 for (int i = 0; i < length; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
418 MonitorInfo* monitor = list->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
419 assert(monitor->owner(), "This monitor must have an owning object");
a61af66fc99e Initial load
duke
parents:
diff changeset
420 _locked_monitors->append(monitor->owner());
a61af66fc99e Initial load
duke
parents:
diff changeset
421 }
a61af66fc99e Initial load
duke
parents:
diff changeset
422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
423 }
a61af66fc99e Initial load
duke
parents:
diff changeset
424 }
a61af66fc99e Initial load
duke
parents:
diff changeset
425
a61af66fc99e Initial load
duke
parents:
diff changeset
426 void StackFrameInfo::oops_do(OopClosure* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
427 f->do_oop((oop*) &_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
428 if (_locked_monitors != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
429 int length = _locked_monitors->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
430 for (int i = 0; i < length; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
431 f->do_oop((oop*) _locked_monitors->adr_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
434 }
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 void StackFrameInfo::print_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
437 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
438 java_lang_Throwable::print_stack_element(st, method(), bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
439 int len = (_locked_monitors != NULL ? _locked_monitors->length() : 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
440 for (int i = 0; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
441 oop o = _locked_monitors->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
442 instanceKlass* ik = instanceKlass::cast(o->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
443 st->print_cr("\t- locked <" INTPTR_FORMAT "> (a %s)", (address)o, ik->external_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
445
a61af66fc99e Initial load
duke
parents:
diff changeset
446 }
a61af66fc99e Initial load
duke
parents:
diff changeset
447
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // Iterate through monitor cache to find JNI locked monitors
a61af66fc99e Initial load
duke
parents:
diff changeset
449 class InflatedMonitorsClosure: public MonitorClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
450 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
451 ThreadStackTrace* _stack_trace;
a61af66fc99e Initial load
duke
parents:
diff changeset
452 Thread* _thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
453 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
454 InflatedMonitorsClosure(Thread* t, ThreadStackTrace* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
455 _thread = t;
a61af66fc99e Initial load
duke
parents:
diff changeset
456 _stack_trace = st;
a61af66fc99e Initial load
duke
parents:
diff changeset
457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
458 void do_monitor(ObjectMonitor* mid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
459 if (mid->owner() == _thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
460 oop object = (oop) mid->object();
a61af66fc99e Initial load
duke
parents:
diff changeset
461 if (!_stack_trace->is_owned_monitor_on_stack(object)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
462 _stack_trace->add_jni_locked_monitor(object);
a61af66fc99e Initial load
duke
parents:
diff changeset
463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
464 }
a61af66fc99e Initial load
duke
parents:
diff changeset
465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
466 };
a61af66fc99e Initial load
duke
parents:
diff changeset
467
a61af66fc99e Initial load
duke
parents:
diff changeset
468 ThreadStackTrace::ThreadStackTrace(JavaThread* t, bool with_locked_monitors) {
a61af66fc99e Initial load
duke
parents:
diff changeset
469 _thread = t;
a61af66fc99e Initial load
duke
parents:
diff changeset
470 _frames = new (ResourceObj::C_HEAP) GrowableArray<StackFrameInfo*>(INITIAL_ARRAY_SIZE, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
471 _depth = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
472 _with_locked_monitors = with_locked_monitors;
a61af66fc99e Initial load
duke
parents:
diff changeset
473 if (_with_locked_monitors) {
a61af66fc99e Initial load
duke
parents:
diff changeset
474 _jni_locked_monitors = new (ResourceObj::C_HEAP) GrowableArray<oop>(INITIAL_ARRAY_SIZE, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
475 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
476 _jni_locked_monitors = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
478 }
a61af66fc99e Initial load
duke
parents:
diff changeset
479
a61af66fc99e Initial load
duke
parents:
diff changeset
480 ThreadStackTrace::~ThreadStackTrace() {
a61af66fc99e Initial load
duke
parents:
diff changeset
481 for (int i = 0; i < _frames->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
482 delete _frames->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
483 }
a61af66fc99e Initial load
duke
parents:
diff changeset
484 delete _frames;
a61af66fc99e Initial load
duke
parents:
diff changeset
485 if (_jni_locked_monitors != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
486 delete _jni_locked_monitors;
a61af66fc99e Initial load
duke
parents:
diff changeset
487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
489
a61af66fc99e Initial load
duke
parents:
diff changeset
490 void ThreadStackTrace::dump_stack_at_safepoint(int maxDepth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
491 assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped");
a61af66fc99e Initial load
duke
parents:
diff changeset
492
a61af66fc99e Initial load
duke
parents:
diff changeset
493 if (_thread->has_last_Java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
494 RegisterMap reg_map(_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
495 vframe* start_vf = _thread->last_java_vframe(&reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
496 int count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
497 for (vframe* f = start_vf; f; f = f->sender() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
498 if (f->is_java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
499 javaVFrame* jvf = javaVFrame::cast(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
500 add_stack_frame(jvf);
a61af66fc99e Initial load
duke
parents:
diff changeset
501 count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
502 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
503 // Ignore non-Java frames
a61af66fc99e Initial load
duke
parents:
diff changeset
504 }
a61af66fc99e Initial load
duke
parents:
diff changeset
505 if (maxDepth > 0 && count == maxDepth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
506 // Skip frames if more than maxDepth
a61af66fc99e Initial load
duke
parents:
diff changeset
507 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
508 }
a61af66fc99e Initial load
duke
parents:
diff changeset
509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
510 }
a61af66fc99e Initial load
duke
parents:
diff changeset
511
a61af66fc99e Initial load
duke
parents:
diff changeset
512 if (_with_locked_monitors) {
a61af66fc99e Initial load
duke
parents:
diff changeset
513 // Iterate inflated monitors and find monitors locked by this thread
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // not found in the stack
a61af66fc99e Initial load
duke
parents:
diff changeset
515 InflatedMonitorsClosure imc(_thread, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
516 ObjectSynchronizer::monitors_iterate(&imc);
a61af66fc99e Initial load
duke
parents:
diff changeset
517 }
a61af66fc99e Initial load
duke
parents:
diff changeset
518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
519
a61af66fc99e Initial load
duke
parents:
diff changeset
520
a61af66fc99e Initial load
duke
parents:
diff changeset
521 bool ThreadStackTrace::is_owned_monitor_on_stack(oop object) {
a61af66fc99e Initial load
duke
parents:
diff changeset
522 assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped");
a61af66fc99e Initial load
duke
parents:
diff changeset
523
a61af66fc99e Initial load
duke
parents:
diff changeset
524 bool found = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
525 int num_frames = get_stack_depth();
a61af66fc99e Initial load
duke
parents:
diff changeset
526 for (int depth = 0; depth < num_frames; depth++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
527 StackFrameInfo* frame = stack_frame_at(depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
528 int len = frame->num_locked_monitors();
a61af66fc99e Initial load
duke
parents:
diff changeset
529 GrowableArray<oop>* locked_monitors = frame->locked_monitors();
a61af66fc99e Initial load
duke
parents:
diff changeset
530 for (int j = 0; j < len; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
531 oop monitor = locked_monitors->at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
532 assert(monitor != NULL && monitor->is_instance(), "must be a Java object");
a61af66fc99e Initial load
duke
parents:
diff changeset
533 if (monitor == object) {
a61af66fc99e Initial load
duke
parents:
diff changeset
534 found = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
535 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
536 }
a61af66fc99e Initial load
duke
parents:
diff changeset
537 }
a61af66fc99e Initial load
duke
parents:
diff changeset
538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
539 return found;
a61af66fc99e Initial load
duke
parents:
diff changeset
540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
541
a61af66fc99e Initial load
duke
parents:
diff changeset
542 Handle ThreadStackTrace::allocate_fill_stack_trace_element_array(TRAPS) {
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 948
diff changeset
543 klassOop k = SystemDictionary::StackTraceElement_klass();
132
60b728ec77c1 6652736: well known classes in system dictionary are inefficiently processed
jrose
parents: 0
diff changeset
544 assert(k != NULL, "must be loaded in 1.4+");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
545 instanceKlassHandle ik(THREAD, k);
a61af66fc99e Initial load
duke
parents:
diff changeset
546
a61af66fc99e Initial load
duke
parents:
diff changeset
547 // Allocate an array of java/lang/StackTraceElement object
a61af66fc99e Initial load
duke
parents:
diff changeset
548 objArrayOop ste = oopFactory::new_objArray(ik(), _depth, CHECK_NH);
a61af66fc99e Initial load
duke
parents:
diff changeset
549 objArrayHandle backtrace(THREAD, ste);
a61af66fc99e Initial load
duke
parents:
diff changeset
550 for (int j = 0; j < _depth; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
551 StackFrameInfo* frame = _frames->at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
552 methodHandle mh(THREAD, frame->method());
a61af66fc99e Initial load
duke
parents:
diff changeset
553 oop element = java_lang_StackTraceElement::create(mh, frame->bci(), CHECK_NH);
a61af66fc99e Initial load
duke
parents:
diff changeset
554 backtrace->obj_at_put(j, element);
a61af66fc99e Initial load
duke
parents:
diff changeset
555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
556 return backtrace;
a61af66fc99e Initial load
duke
parents:
diff changeset
557 }
a61af66fc99e Initial load
duke
parents:
diff changeset
558
a61af66fc99e Initial load
duke
parents:
diff changeset
559 void ThreadStackTrace::add_stack_frame(javaVFrame* jvf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
560 StackFrameInfo* frame = new StackFrameInfo(jvf, _with_locked_monitors);
a61af66fc99e Initial load
duke
parents:
diff changeset
561 _frames->append(frame);
a61af66fc99e Initial load
duke
parents:
diff changeset
562 _depth++;
a61af66fc99e Initial load
duke
parents:
diff changeset
563 }
a61af66fc99e Initial load
duke
parents:
diff changeset
564
a61af66fc99e Initial load
duke
parents:
diff changeset
565 void ThreadStackTrace::oops_do(OopClosure* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
566 int length = _frames->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
567 for (int i = 0; i < length; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
568 _frames->at(i)->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
570
a61af66fc99e Initial load
duke
parents:
diff changeset
571 length = (_jni_locked_monitors != NULL ? _jni_locked_monitors->length() : 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
572 for (int j = 0; j < length; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
573 f->do_oop((oop*) _jni_locked_monitors->adr_at(j));
a61af66fc99e Initial load
duke
parents:
diff changeset
574 }
a61af66fc99e Initial load
duke
parents:
diff changeset
575 }
a61af66fc99e Initial load
duke
parents:
diff changeset
576
a61af66fc99e Initial load
duke
parents:
diff changeset
577 ConcurrentLocksDump::~ConcurrentLocksDump() {
a61af66fc99e Initial load
duke
parents:
diff changeset
578 if (_retain_map_on_free) {
a61af66fc99e Initial load
duke
parents:
diff changeset
579 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
580 }
a61af66fc99e Initial load
duke
parents:
diff changeset
581
a61af66fc99e Initial load
duke
parents:
diff changeset
582 for (ThreadConcurrentLocks* t = _map; t != NULL;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
583 ThreadConcurrentLocks* tcl = t;
a61af66fc99e Initial load
duke
parents:
diff changeset
584 t = t->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
585 delete tcl;
a61af66fc99e Initial load
duke
parents:
diff changeset
586 }
a61af66fc99e Initial load
duke
parents:
diff changeset
587 }
a61af66fc99e Initial load
duke
parents:
diff changeset
588
a61af66fc99e Initial load
duke
parents:
diff changeset
589 void ConcurrentLocksDump::dump_at_safepoint() {
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // dump all locked concurrent locks
a61af66fc99e Initial load
duke
parents:
diff changeset
591 assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped");
a61af66fc99e Initial load
duke
parents:
diff changeset
592
a61af66fc99e Initial load
duke
parents:
diff changeset
593 if (JDK_Version::is_gte_jdk16x_version()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
594 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
595
a61af66fc99e Initial load
duke
parents:
diff changeset
596 GrowableArray<oop>* aos_objects = new GrowableArray<oop>(INITIAL_ARRAY_SIZE);
a61af66fc99e Initial load
duke
parents:
diff changeset
597
a61af66fc99e Initial load
duke
parents:
diff changeset
598 // Find all instances of AbstractOwnableSynchronizer
a61af66fc99e Initial load
duke
parents:
diff changeset
599 HeapInspection::find_instances_at_safepoint(SystemDictionary::abstract_ownable_synchronizer_klass(),
a61af66fc99e Initial load
duke
parents:
diff changeset
600 aos_objects);
a61af66fc99e Initial load
duke
parents:
diff changeset
601 // Build a map of thread to its owned AQS locks
a61af66fc99e Initial load
duke
parents:
diff changeset
602 build_map(aos_objects);
a61af66fc99e Initial load
duke
parents:
diff changeset
603 }
a61af66fc99e Initial load
duke
parents:
diff changeset
604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
605
a61af66fc99e Initial load
duke
parents:
diff changeset
606
a61af66fc99e Initial load
duke
parents:
diff changeset
607 // build a map of JavaThread to all its owned AbstractOwnableSynchronizer
a61af66fc99e Initial load
duke
parents:
diff changeset
608 void ConcurrentLocksDump::build_map(GrowableArray<oop>* aos_objects) {
a61af66fc99e Initial load
duke
parents:
diff changeset
609 int length = aos_objects->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
610 for (int i = 0; i < length; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
611 oop o = aos_objects->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
612 oop owner_thread_obj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
613 if (owner_thread_obj != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
614 JavaThread* thread = java_lang_Thread::thread(owner_thread_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
615 assert(o->is_instance(), "Must be an instanceOop");
a61af66fc99e Initial load
duke
parents:
diff changeset
616 add_lock(thread, (instanceOop) o);
a61af66fc99e Initial load
duke
parents:
diff changeset
617 }
a61af66fc99e Initial load
duke
parents:
diff changeset
618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
619 }
a61af66fc99e Initial load
duke
parents:
diff changeset
620
a61af66fc99e Initial load
duke
parents:
diff changeset
621 void ConcurrentLocksDump::add_lock(JavaThread* thread, instanceOop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
622 ThreadConcurrentLocks* tcl = thread_concurrent_locks(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
623 if (tcl != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
624 tcl->add_lock(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
625 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
627
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // First owned lock found for this thread
a61af66fc99e Initial load
duke
parents:
diff changeset
629 tcl = new ThreadConcurrentLocks(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
630 tcl->add_lock(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
631 if (_map == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
632 _map = tcl;
a61af66fc99e Initial load
duke
parents:
diff changeset
633 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
634 _last->set_next(tcl);
a61af66fc99e Initial load
duke
parents:
diff changeset
635 }
a61af66fc99e Initial load
duke
parents:
diff changeset
636 _last = tcl;
a61af66fc99e Initial load
duke
parents:
diff changeset
637 }
a61af66fc99e Initial load
duke
parents:
diff changeset
638
a61af66fc99e Initial load
duke
parents:
diff changeset
639 ThreadConcurrentLocks* ConcurrentLocksDump::thread_concurrent_locks(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
640 for (ThreadConcurrentLocks* tcl = _map; tcl != NULL; tcl = tcl->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
641 if (tcl->java_thread() == thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
642 return tcl;
a61af66fc99e Initial load
duke
parents:
diff changeset
643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
644 }
a61af66fc99e Initial load
duke
parents:
diff changeset
645 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
647
a61af66fc99e Initial load
duke
parents:
diff changeset
648 void ConcurrentLocksDump::print_locks_on(JavaThread* t, outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
649 st->print_cr(" Locked ownable synchronizers:");
a61af66fc99e Initial load
duke
parents:
diff changeset
650 ThreadConcurrentLocks* tcl = thread_concurrent_locks(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
651 GrowableArray<instanceOop>* locks = (tcl != NULL ? tcl->owned_locks() : NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
652 if (locks == NULL || locks->is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
653 st->print_cr("\t- None");
a61af66fc99e Initial load
duke
parents:
diff changeset
654 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
655 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
656 }
a61af66fc99e Initial load
duke
parents:
diff changeset
657
a61af66fc99e Initial load
duke
parents:
diff changeset
658 for (int i = 0; i < locks->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
659 instanceOop obj = locks->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
660 instanceKlass* ik = instanceKlass::cast(obj->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
661 st->print_cr("\t- <" INTPTR_FORMAT "> (a %s)", (address)obj, ik->external_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
663 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
665
a61af66fc99e Initial load
duke
parents:
diff changeset
666 ThreadConcurrentLocks::ThreadConcurrentLocks(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
667 _thread = thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
668 _owned_locks = new (ResourceObj::C_HEAP) GrowableArray<instanceOop>(INITIAL_ARRAY_SIZE, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
669 _next = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
670 }
a61af66fc99e Initial load
duke
parents:
diff changeset
671
a61af66fc99e Initial load
duke
parents:
diff changeset
672 ThreadConcurrentLocks::~ThreadConcurrentLocks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
673 delete _owned_locks;
a61af66fc99e Initial load
duke
parents:
diff changeset
674 }
a61af66fc99e Initial load
duke
parents:
diff changeset
675
a61af66fc99e Initial load
duke
parents:
diff changeset
676 void ThreadConcurrentLocks::add_lock(instanceOop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
677 _owned_locks->append(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
678 }
a61af66fc99e Initial load
duke
parents:
diff changeset
679
a61af66fc99e Initial load
duke
parents:
diff changeset
680 void ThreadConcurrentLocks::oops_do(OopClosure* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
681 int length = _owned_locks->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
682 for (int i = 0; i < length; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
683 f->do_oop((oop*) _owned_locks->adr_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
684 }
a61af66fc99e Initial load
duke
parents:
diff changeset
685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
686
a61af66fc99e Initial load
duke
parents:
diff changeset
687 ThreadStatistics::ThreadStatistics() {
a61af66fc99e Initial load
duke
parents:
diff changeset
688 _contended_enter_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
689 _monitor_wait_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
690 _sleep_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
691 _count_pending_reset = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
692 _timer_pending_reset = false;
875
6a93908f268f 6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents: 242
diff changeset
693 memset((void*) _perf_recursion_counts, 0, sizeof(_perf_recursion_counts));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
695
a61af66fc99e Initial load
duke
parents:
diff changeset
696 ThreadSnapshot::ThreadSnapshot(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
697 _thread = thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
698 _threadObj = thread->threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
699 _stack_trace = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
700 _concurrent_locks = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
701 _next = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
702
a61af66fc99e Initial load
duke
parents:
diff changeset
703 ThreadStatistics* stat = thread->get_thread_stat();
a61af66fc99e Initial load
duke
parents:
diff changeset
704 _contended_enter_ticks = stat->contended_enter_ticks();
a61af66fc99e Initial load
duke
parents:
diff changeset
705 _contended_enter_count = stat->contended_enter_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
706 _monitor_wait_ticks = stat->monitor_wait_ticks();
a61af66fc99e Initial load
duke
parents:
diff changeset
707 _monitor_wait_count = stat->monitor_wait_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
708 _sleep_ticks = stat->sleep_ticks();
a61af66fc99e Initial load
duke
parents:
diff changeset
709 _sleep_count = stat->sleep_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
710
a61af66fc99e Initial load
duke
parents:
diff changeset
711 _blocker_object = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
712 _blocker_object_owner = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
713
a61af66fc99e Initial load
duke
parents:
diff changeset
714 _thread_status = java_lang_Thread::get_thread_status(_threadObj);
a61af66fc99e Initial load
duke
parents:
diff changeset
715 _is_ext_suspended = thread->is_being_ext_suspended();
a61af66fc99e Initial load
duke
parents:
diff changeset
716 _is_in_native = (thread->thread_state() == _thread_in_native);
a61af66fc99e Initial load
duke
parents:
diff changeset
717
a61af66fc99e Initial load
duke
parents:
diff changeset
718 if (_thread_status == java_lang_Thread::BLOCKED_ON_MONITOR_ENTER ||
a61af66fc99e Initial load
duke
parents:
diff changeset
719 _thread_status == java_lang_Thread::IN_OBJECT_WAIT ||
a61af66fc99e Initial load
duke
parents:
diff changeset
720 _thread_status == java_lang_Thread::IN_OBJECT_WAIT_TIMED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
721
a61af66fc99e Initial load
duke
parents:
diff changeset
722 Handle obj = ThreadService::get_current_contended_monitor(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
723 if (obj() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
724 // monitor no longer exists; thread is not blocked
a61af66fc99e Initial load
duke
parents:
diff changeset
725 _thread_status = java_lang_Thread::RUNNABLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
726 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
727 _blocker_object = obj();
a61af66fc99e Initial load
duke
parents:
diff changeset
728 JavaThread* owner = ObjectSynchronizer::get_lock_owner(obj, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
729 if ((owner == NULL && _thread_status == java_lang_Thread::BLOCKED_ON_MONITOR_ENTER)
a61af66fc99e Initial load
duke
parents:
diff changeset
730 || (owner != NULL && owner->is_attaching())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
731 // ownership information of the monitor is not available
a61af66fc99e Initial load
duke
parents:
diff changeset
732 // (may no longer be owned or releasing to some other thread)
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // make this thread in RUNNABLE state.
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // And when the owner thread is in attaching state, the java thread
a61af66fc99e Initial load
duke
parents:
diff changeset
735 // is not completely initialized. For example thread name and id
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // and may not be set, so hide the attaching thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
737 _thread_status = java_lang_Thread::RUNNABLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
738 _blocker_object = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
739 } else if (owner != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
740 _blocker_object_owner = owner->threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
742 }
a61af66fc99e Initial load
duke
parents:
diff changeset
743 }
a61af66fc99e Initial load
duke
parents:
diff changeset
744
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // Support for JSR-166 locks
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 196
diff changeset
746 if (JDK_Version::current().supports_thread_park_blocker() &&
0
a61af66fc99e Initial load
duke
parents:
diff changeset
747 (_thread_status == java_lang_Thread::PARKED ||
a61af66fc99e Initial load
duke
parents:
diff changeset
748 _thread_status == java_lang_Thread::PARKED_TIMED)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
749
a61af66fc99e Initial load
duke
parents:
diff changeset
750 _blocker_object = thread->current_park_blocker();
a61af66fc99e Initial load
duke
parents:
diff changeset
751 if (_blocker_object != NULL && _blocker_object->is_a(SystemDictionary::abstract_ownable_synchronizer_klass())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
752 _blocker_object_owner = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(_blocker_object);
a61af66fc99e Initial load
duke
parents:
diff changeset
753 }
a61af66fc99e Initial load
duke
parents:
diff changeset
754 }
a61af66fc99e Initial load
duke
parents:
diff changeset
755 }
a61af66fc99e Initial load
duke
parents:
diff changeset
756
a61af66fc99e Initial load
duke
parents:
diff changeset
757 ThreadSnapshot::~ThreadSnapshot() {
a61af66fc99e Initial load
duke
parents:
diff changeset
758 delete _stack_trace;
a61af66fc99e Initial load
duke
parents:
diff changeset
759 delete _concurrent_locks;
a61af66fc99e Initial load
duke
parents:
diff changeset
760 }
a61af66fc99e Initial load
duke
parents:
diff changeset
761
a61af66fc99e Initial load
duke
parents:
diff changeset
762 void ThreadSnapshot::dump_stack_at_safepoint(int max_depth, bool with_locked_monitors) {
a61af66fc99e Initial load
duke
parents:
diff changeset
763 _stack_trace = new ThreadStackTrace(_thread, with_locked_monitors);
a61af66fc99e Initial load
duke
parents:
diff changeset
764 _stack_trace->dump_stack_at_safepoint(max_depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
765 }
a61af66fc99e Initial load
duke
parents:
diff changeset
766
a61af66fc99e Initial load
duke
parents:
diff changeset
767
a61af66fc99e Initial load
duke
parents:
diff changeset
768 void ThreadSnapshot::oops_do(OopClosure* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
769 f->do_oop(&_threadObj);
a61af66fc99e Initial load
duke
parents:
diff changeset
770 f->do_oop(&_blocker_object);
a61af66fc99e Initial load
duke
parents:
diff changeset
771 f->do_oop(&_blocker_object_owner);
a61af66fc99e Initial load
duke
parents:
diff changeset
772 if (_stack_trace != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
773 _stack_trace->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
774 }
a61af66fc99e Initial load
duke
parents:
diff changeset
775 if (_concurrent_locks != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
776 _concurrent_locks->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
777 }
a61af66fc99e Initial load
duke
parents:
diff changeset
778 }
a61af66fc99e Initial load
duke
parents:
diff changeset
779
a61af66fc99e Initial load
duke
parents:
diff changeset
780 DeadlockCycle::DeadlockCycle() {
a61af66fc99e Initial load
duke
parents:
diff changeset
781 _is_deadlock = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
782 _threads = new (ResourceObj::C_HEAP) GrowableArray<JavaThread*>(INITIAL_ARRAY_SIZE, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
783 _next = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
784 }
a61af66fc99e Initial load
duke
parents:
diff changeset
785
a61af66fc99e Initial load
duke
parents:
diff changeset
786 DeadlockCycle::~DeadlockCycle() {
a61af66fc99e Initial load
duke
parents:
diff changeset
787 delete _threads;
a61af66fc99e Initial load
duke
parents:
diff changeset
788 }
a61af66fc99e Initial load
duke
parents:
diff changeset
789
a61af66fc99e Initial load
duke
parents:
diff changeset
790 void DeadlockCycle::print_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
791 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
792 st->print_cr("Found one Java-level deadlock:");
a61af66fc99e Initial load
duke
parents:
diff changeset
793 st->print("=============================");
a61af66fc99e Initial load
duke
parents:
diff changeset
794
a61af66fc99e Initial load
duke
parents:
diff changeset
795 JavaThread* currentThread;
a61af66fc99e Initial load
duke
parents:
diff changeset
796 ObjectMonitor* waitingToLockMonitor;
a61af66fc99e Initial load
duke
parents:
diff changeset
797 oop waitingToLockBlocker;
a61af66fc99e Initial load
duke
parents:
diff changeset
798 int len = _threads->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
799 for (int i = 0; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
800 currentThread = _threads->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
801 waitingToLockMonitor = (ObjectMonitor*)currentThread->current_pending_monitor();
a61af66fc99e Initial load
duke
parents:
diff changeset
802 waitingToLockBlocker = currentThread->current_park_blocker();
a61af66fc99e Initial load
duke
parents:
diff changeset
803 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
804 st->print_cr("\"%s\":", currentThread->get_thread_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
805 const char* owner_desc = ",\n which is held by";
a61af66fc99e Initial load
duke
parents:
diff changeset
806 if (waitingToLockMonitor != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
807 st->print(" waiting to lock monitor " INTPTR_FORMAT, waitingToLockMonitor);
a61af66fc99e Initial load
duke
parents:
diff changeset
808 oop obj = (oop)waitingToLockMonitor->object();
a61af66fc99e Initial load
duke
parents:
diff changeset
809 if (obj != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
810 st->print(" (object "INTPTR_FORMAT ", a %s)", (address)obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
811 (instanceKlass::cast(obj->klass()))->external_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
812
a61af66fc99e Initial load
duke
parents:
diff changeset
813 if (!currentThread->current_pending_monitor_is_from_java()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
814 owner_desc = "\n in JNI, which is held by";
a61af66fc99e Initial load
duke
parents:
diff changeset
815 }
a61af66fc99e Initial load
duke
parents:
diff changeset
816 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
817 // No Java object associated - a JVMTI raw monitor
a61af66fc99e Initial load
duke
parents:
diff changeset
818 owner_desc = " (JVMTI raw monitor),\n which is held by";
a61af66fc99e Initial load
duke
parents:
diff changeset
819 }
a61af66fc99e Initial load
duke
parents:
diff changeset
820 currentThread = Threads::owning_thread_from_monitor_owner(
a61af66fc99e Initial load
duke
parents:
diff changeset
821 (address)waitingToLockMonitor->owner(), false /* no locking needed */);
a61af66fc99e Initial load
duke
parents:
diff changeset
822 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
823 st->print(" waiting for ownable synchronizer " INTPTR_FORMAT ", (a %s)",
a61af66fc99e Initial load
duke
parents:
diff changeset
824 (address)waitingToLockBlocker,
a61af66fc99e Initial load
duke
parents:
diff changeset
825 (instanceKlass::cast(waitingToLockBlocker->klass()))->external_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
826 assert(waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass()),
a61af66fc99e Initial load
duke
parents:
diff changeset
827 "Must be an AbstractOwnableSynchronizer");
a61af66fc99e Initial load
duke
parents:
diff changeset
828 oop ownerObj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(waitingToLockBlocker);
a61af66fc99e Initial load
duke
parents:
diff changeset
829 currentThread = java_lang_Thread::thread(ownerObj);
a61af66fc99e Initial load
duke
parents:
diff changeset
830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
831 st->print("%s \"%s\"", owner_desc, currentThread->get_thread_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
832 }
a61af66fc99e Initial load
duke
parents:
diff changeset
833
a61af66fc99e Initial load
duke
parents:
diff changeset
834 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
835 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
836
a61af66fc99e Initial load
duke
parents:
diff changeset
837 // Print stack traces
a61af66fc99e Initial load
duke
parents:
diff changeset
838 bool oldJavaMonitorsInStackTrace = JavaMonitorsInStackTrace;
a61af66fc99e Initial load
duke
parents:
diff changeset
839 JavaMonitorsInStackTrace = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
840 st->print_cr("Java stack information for the threads listed above:");
a61af66fc99e Initial load
duke
parents:
diff changeset
841 st->print_cr("===================================================");
a61af66fc99e Initial load
duke
parents:
diff changeset
842 for (int j = 0; j < len; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
843 currentThread = _threads->at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
844 st->print_cr("\"%s\":", currentThread->get_thread_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
845 currentThread->print_stack_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
846 }
a61af66fc99e Initial load
duke
parents:
diff changeset
847 JavaMonitorsInStackTrace = oldJavaMonitorsInStackTrace;
a61af66fc99e Initial load
duke
parents:
diff changeset
848 }
a61af66fc99e Initial load
duke
parents:
diff changeset
849
a61af66fc99e Initial load
duke
parents:
diff changeset
850 ThreadsListEnumerator::ThreadsListEnumerator(Thread* cur_thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
851 bool include_jvmti_agent_threads,
a61af66fc99e Initial load
duke
parents:
diff changeset
852 bool include_jni_attaching_threads) {
a61af66fc99e Initial load
duke
parents:
diff changeset
853 assert(cur_thread == Thread::current(), "Check current thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
854
a61af66fc99e Initial load
duke
parents:
diff changeset
855 int init_size = ThreadService::get_live_thread_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
856 _threads_array = new GrowableArray<instanceHandle>(init_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
857
a61af66fc99e Initial load
duke
parents:
diff changeset
858 MutexLockerEx ml(Threads_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
859
a61af66fc99e Initial load
duke
parents:
diff changeset
860 for (JavaThread* jt = Threads::first(); jt != NULL; jt = jt->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
861 // skips JavaThreads in the process of exiting
a61af66fc99e Initial load
duke
parents:
diff changeset
862 // and also skips VM internal JavaThreads
a61af66fc99e Initial load
duke
parents:
diff changeset
863 // Threads in _thread_new or _thread_new_trans state are included.
a61af66fc99e Initial load
duke
parents:
diff changeset
864 // i.e. threads have been started but not yet running.
a61af66fc99e Initial load
duke
parents:
diff changeset
865 if (jt->threadObj() == NULL ||
a61af66fc99e Initial load
duke
parents:
diff changeset
866 jt->is_exiting() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
867 !java_lang_Thread::is_alive(jt->threadObj()) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
868 jt->is_hidden_from_external_view()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
869 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
870 }
a61af66fc99e Initial load
duke
parents:
diff changeset
871
a61af66fc99e Initial load
duke
parents:
diff changeset
872 // skip agent threads
a61af66fc99e Initial load
duke
parents:
diff changeset
873 if (!include_jvmti_agent_threads && jt->is_jvmti_agent_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
874 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877 // skip jni threads in the process of attaching
a61af66fc99e Initial load
duke
parents:
diff changeset
878 if (!include_jni_attaching_threads && jt->is_attaching()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
879 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
880 }
a61af66fc99e Initial load
duke
parents:
diff changeset
881
a61af66fc99e Initial load
duke
parents:
diff changeset
882 instanceHandle h(cur_thread, (instanceOop) jt->threadObj());
a61af66fc99e Initial load
duke
parents:
diff changeset
883 _threads_array->append(h);
a61af66fc99e Initial load
duke
parents:
diff changeset
884 }
a61af66fc99e Initial load
duke
parents:
diff changeset
885 }