Mercurial > hg > truffle
annotate src/share/vm/runtime/vm_operations.cpp @ 6972:bd7a7ce2e264
6830717: replay of compilations would help with debugging
Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method.
Reviewed-by: kvn, twisti, sspitsyn
Contributed-by: yumin.qi@oracle.com
author | minqi |
---|---|
date | Mon, 12 Nov 2012 14:03:53 -0800 |
parents | f08d439fab8c |
children | 0ebca2e35ca5 f34d701e952e |
rev | line source |
---|---|
0 | 1 /* |
2426
1d1603768966
7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents:
2177
diff
changeset
|
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1202
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1202
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:
1202
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
26 #include "classfile/symbolTable.hpp" |
1972 | 27 #include "classfile/vmSymbols.hpp" |
28 #include "compiler/compileBroker.hpp" | |
29 #include "compiler/compilerOracle.hpp" | |
30 #include "gc_implementation/shared/isGCActiveMark.hpp" | |
31 #include "memory/resourceArea.hpp" | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
32 #include "oops/symbol.hpp" |
1972 | 33 #include "runtime/arguments.hpp" |
34 #include "runtime/deoptimization.hpp" | |
35 #include "runtime/interfaceSupport.hpp" | |
36 #include "runtime/sweeper.hpp" | |
37 #include "runtime/vm_operations.hpp" | |
38 #include "services/threadService.hpp" | |
39 #ifdef TARGET_OS_FAMILY_linux | |
40 # include "thread_linux.inline.hpp" | |
41 #endif | |
42 #ifdef TARGET_OS_FAMILY_solaris | |
43 # include "thread_solaris.inline.hpp" | |
44 #endif | |
45 #ifdef TARGET_OS_FAMILY_windows | |
46 # include "thread_windows.inline.hpp" | |
47 #endif | |
3960 | 48 #ifdef TARGET_OS_FAMILY_bsd |
49 # include "thread_bsd.inline.hpp" | |
50 #endif | |
0 | 51 |
52 #define VM_OP_NAME_INITIALIZE(name) #name, | |
53 | |
54 const char* VM_Operation::_names[VM_Operation::VMOp_Terminating] = \ | |
55 { VM_OPS_DO(VM_OP_NAME_INITIALIZE) }; | |
56 | |
57 void VM_Operation::set_calling_thread(Thread* thread, ThreadPriority priority) { | |
58 _calling_thread = thread; | |
59 assert(MinPriority <= priority && priority <= MaxPriority, "sanity check"); | |
60 _priority = priority; | |
61 } | |
62 | |
63 | |
64 void VM_Operation::evaluate() { | |
65 ResourceMark rm; | |
66 if (TraceVMOperation) { | |
67 tty->print("["); | |
68 NOT_PRODUCT(print();) | |
69 } | |
70 doit(); | |
71 if (TraceVMOperation) { | |
72 tty->print_cr("]"); | |
73 } | |
74 } | |
75 | |
76 // Called by fatal error handler. | |
77 void VM_Operation::print_on_error(outputStream* st) const { | |
78 st->print("VM_Operation (" PTR_FORMAT "): ", this); | |
79 st->print("%s", name()); | |
80 | |
81 const char* mode; | |
82 switch(evaluation_mode()) { | |
83 case _safepoint : mode = "safepoint"; break; | |
84 case _no_safepoint : mode = "no safepoint"; break; | |
85 case _concurrent : mode = "concurrent"; break; | |
86 case _async_safepoint: mode = "async safepoint"; break; | |
87 default : mode = "unknown"; break; | |
88 } | |
89 st->print(", mode: %s", mode); | |
90 | |
91 if (calling_thread()) { | |
92 st->print(", requested by thread " PTR_FORMAT, calling_thread()); | |
93 } | |
94 } | |
95 | |
96 void VM_ThreadStop::doit() { | |
97 assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); | |
98 JavaThread* target = java_lang_Thread::thread(target_thread()); | |
99 // Note that this now allows multiple ThreadDeath exceptions to be | |
100 // thrown at a thread. | |
101 if (target != NULL) { | |
102 // the thread has run and is not already in the process of exiting | |
103 target->send_thread_stop(throwable()); | |
104 } | |
105 } | |
106 | |
107 void VM_Deoptimize::doit() { | |
108 // We do not want any GCs to happen while we are in the middle of this VM operation | |
109 ResourceMark rm; | |
110 DeoptimizationMarker dm; | |
111 | |
112 // Deoptimize all activations depending on marked nmethods | |
113 Deoptimization::deoptimize_dependents(); | |
114 | |
115 // Make the dependent methods zombies | |
116 CodeCache::make_marked_nmethods_zombies(); | |
117 } | |
118 | |
119 | |
120 VM_DeoptimizeFrame::VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id) { | |
121 _thread = thread; | |
122 _id = id; | |
123 } | |
124 | |
125 | |
126 void VM_DeoptimizeFrame::doit() { | |
1905
ce6848d0666d
6968367: can_post_on_exceptions is still using VM_DeoptimizeFrame in some places
never
parents:
1552
diff
changeset
|
127 Deoptimization::deoptimize_frame_internal(_thread, _id); |
0 | 128 } |
129 | |
130 | |
131 #ifndef PRODUCT | |
132 | |
133 void VM_DeoptimizeAll::doit() { | |
134 DeoptimizationMarker dm; | |
135 // deoptimize all java threads in the system | |
136 if (DeoptimizeALot) { | |
137 for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) { | |
138 if (thread->has_last_Java_frame()) { | |
139 thread->deoptimize(); | |
140 } | |
141 } | |
142 } else if (DeoptimizeRandom) { | |
143 | |
144 // Deoptimize some selected threads and frames | |
145 int tnum = os::random() & 0x3; | |
146 int fnum = os::random() & 0x3; | |
147 int tcount = 0; | |
148 for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) { | |
149 if (thread->has_last_Java_frame()) { | |
150 if (tcount++ == tnum) { | |
151 tcount = 0; | |
152 int fcount = 0; | |
153 // Deoptimize some selected frames. | |
154 // Biased llocking wants a updated register map | |
155 for(StackFrameStream fst(thread, UseBiasedLocking); !fst.is_done(); fst.next()) { | |
156 if (fst.current()->can_be_deoptimized()) { | |
157 if (fcount++ == fnum) { | |
158 fcount = 0; | |
159 Deoptimization::deoptimize(thread, *fst.current(), fst.register_map()); | |
160 } | |
161 } | |
162 } | |
163 } | |
164 } | |
165 } | |
166 } | |
167 } | |
168 | |
169 | |
170 void VM_ZombieAll::doit() { | |
171 JavaThread *thread = (JavaThread *)calling_thread(); | |
172 assert(thread->is_Java_thread(), "must be a Java thread"); | |
173 thread->make_zombies(); | |
174 } | |
175 | |
176 #endif // !PRODUCT | |
177 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
178 void VM_UnlinkSymbols::doit() { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
179 JavaThread *thread = (JavaThread *)calling_thread(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
180 assert(thread->is_Java_thread(), "must be a Java thread"); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
181 SymbolTable::unlink(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
182 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
183 |
1202 | 184 void VM_HandleFullCodeCache::doit() { |
185 NMethodSweeper::speculative_disconnect_nmethods(_is_full); | |
186 } | |
187 | |
0 | 188 void VM_Verify::doit() { |
189 Universe::verify(); | |
190 } | |
191 | |
192 bool VM_PrintThreads::doit_prologue() { | |
193 assert(Thread::current()->is_Java_thread(), "just checking"); | |
194 | |
195 // Make sure AbstractOwnableSynchronizer is loaded | |
196 if (JDK_Version::is_gte_jdk16x_version()) { | |
197 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current()); | |
198 } | |
199 | |
200 // Get Heap_lock if concurrent locks will be dumped | |
201 if (_print_concurrent_locks) { | |
202 Heap_lock->lock(); | |
203 } | |
204 return true; | |
205 } | |
206 | |
207 void VM_PrintThreads::doit() { | |
208 Threads::print_on(_out, true, false, _print_concurrent_locks); | |
209 } | |
210 | |
211 void VM_PrintThreads::doit_epilogue() { | |
212 if (_print_concurrent_locks) { | |
213 // Release Heap_lock | |
214 Heap_lock->unlock(); | |
215 } | |
216 } | |
217 | |
218 void VM_PrintJNI::doit() { | |
219 JNIHandles::print_on(_out); | |
220 } | |
221 | |
222 VM_FindDeadlocks::~VM_FindDeadlocks() { | |
223 if (_deadlocks != NULL) { | |
224 DeadlockCycle* cycle = _deadlocks; | |
225 while (cycle != NULL) { | |
226 DeadlockCycle* d = cycle; | |
227 cycle = cycle->next(); | |
228 delete d; | |
229 } | |
230 } | |
231 } | |
232 | |
233 bool VM_FindDeadlocks::doit_prologue() { | |
234 assert(Thread::current()->is_Java_thread(), "just checking"); | |
235 | |
236 // Load AbstractOwnableSynchronizer class | |
237 if (_concurrent_locks && JDK_Version::is_gte_jdk16x_version()) { | |
238 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current()); | |
239 } | |
240 | |
241 return true; | |
242 } | |
243 | |
244 void VM_FindDeadlocks::doit() { | |
245 _deadlocks = ThreadService::find_deadlocks_at_safepoint(_concurrent_locks); | |
246 if (_out != NULL) { | |
247 int num_deadlocks = 0; | |
248 for (DeadlockCycle* cycle = _deadlocks; cycle != NULL; cycle = cycle->next()) { | |
249 num_deadlocks++; | |
250 cycle->print_on(_out); | |
251 } | |
252 | |
253 if (num_deadlocks == 1) { | |
254 _out->print_cr("\nFound 1 deadlock.\n"); | |
255 _out->flush(); | |
256 } else if (num_deadlocks > 1) { | |
257 _out->print_cr("\nFound %d deadlocks.\n", num_deadlocks); | |
258 _out->flush(); | |
259 } | |
260 } | |
261 } | |
262 | |
263 VM_ThreadDump::VM_ThreadDump(ThreadDumpResult* result, | |
264 int max_depth, | |
265 bool with_locked_monitors, | |
266 bool with_locked_synchronizers) { | |
267 _result = result; | |
268 _num_threads = 0; // 0 indicates all threads | |
269 _threads = NULL; | |
270 _result = result; | |
271 _max_depth = max_depth; | |
272 _with_locked_monitors = with_locked_monitors; | |
273 _with_locked_synchronizers = with_locked_synchronizers; | |
274 } | |
275 | |
276 VM_ThreadDump::VM_ThreadDump(ThreadDumpResult* result, | |
277 GrowableArray<instanceHandle>* threads, | |
278 int num_threads, | |
279 int max_depth, | |
280 bool with_locked_monitors, | |
281 bool with_locked_synchronizers) { | |
282 _result = result; | |
283 _num_threads = num_threads; | |
284 _threads = threads; | |
285 _result = result; | |
286 _max_depth = max_depth; | |
287 _with_locked_monitors = with_locked_monitors; | |
288 _with_locked_synchronizers = with_locked_synchronizers; | |
289 } | |
290 | |
291 bool VM_ThreadDump::doit_prologue() { | |
292 assert(Thread::current()->is_Java_thread(), "just checking"); | |
293 | |
294 // Load AbstractOwnableSynchronizer class before taking thread snapshots | |
295 if (JDK_Version::is_gte_jdk16x_version()) { | |
296 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current()); | |
297 } | |
298 | |
299 if (_with_locked_synchronizers) { | |
300 // Acquire Heap_lock to dump concurrent locks | |
301 Heap_lock->lock(); | |
302 } | |
303 | |
304 return true; | |
305 } | |
306 | |
307 void VM_ThreadDump::doit_epilogue() { | |
308 if (_with_locked_synchronizers) { | |
309 // Release Heap_lock | |
310 Heap_lock->unlock(); | |
311 } | |
312 } | |
313 | |
314 void VM_ThreadDump::doit() { | |
315 ResourceMark rm; | |
316 | |
317 ConcurrentLocksDump concurrent_locks(true); | |
318 if (_with_locked_synchronizers) { | |
319 concurrent_locks.dump_at_safepoint(); | |
320 } | |
321 | |
322 if (_num_threads == 0) { | |
323 // Snapshot all live threads | |
324 for (JavaThread* jt = Threads::first(); jt != NULL; jt = jt->next()) { | |
325 if (jt->is_exiting() || | |
326 jt->is_hidden_from_external_view()) { | |
327 // skip terminating threads and hidden threads | |
328 continue; | |
329 } | |
330 ThreadConcurrentLocks* tcl = NULL; | |
331 if (_with_locked_synchronizers) { | |
332 tcl = concurrent_locks.thread_concurrent_locks(jt); | |
333 } | |
334 ThreadSnapshot* ts = snapshot_thread(jt, tcl); | |
335 _result->add_thread_snapshot(ts); | |
336 } | |
337 } else { | |
338 // Snapshot threads in the given _threads array | |
339 // A dummy snapshot is created if a thread doesn't exist | |
340 for (int i = 0; i < _num_threads; i++) { | |
341 instanceHandle th = _threads->at(i); | |
342 if (th() == NULL) { | |
343 // skip if the thread doesn't exist | |
344 // Add a dummy snapshot | |
345 _result->add_thread_snapshot(new ThreadSnapshot()); | |
346 continue; | |
347 } | |
348 | |
349 // Dump thread stack only if the thread is alive and not exiting | |
350 // and not VM internal thread. | |
351 JavaThread* jt = java_lang_Thread::thread(th()); | |
352 if (jt == NULL || /* thread not alive */ | |
353 jt->is_exiting() || | |
354 jt->is_hidden_from_external_view()) { | |
355 // add a NULL snapshot if skipped | |
356 _result->add_thread_snapshot(new ThreadSnapshot()); | |
357 continue; | |
358 } | |
359 ThreadConcurrentLocks* tcl = NULL; | |
360 if (_with_locked_synchronizers) { | |
361 tcl = concurrent_locks.thread_concurrent_locks(jt); | |
362 } | |
363 ThreadSnapshot* ts = snapshot_thread(jt, tcl); | |
364 _result->add_thread_snapshot(ts); | |
365 } | |
366 } | |
367 } | |
368 | |
369 ThreadSnapshot* VM_ThreadDump::snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl) { | |
370 ThreadSnapshot* snapshot = new ThreadSnapshot(java_thread); | |
371 snapshot->dump_stack_at_safepoint(_max_depth, _with_locked_monitors); | |
372 snapshot->set_concurrent_locks(tcl); | |
373 return snapshot; | |
374 } | |
375 | |
376 volatile bool VM_Exit::_vm_exited = false; | |
377 Thread * VM_Exit::_shutdown_thread = NULL; | |
378 | |
379 int VM_Exit::set_vm_exited() { | |
380 Thread * thr_cur = ThreadLocalStorage::get_thread_slow(); | |
381 | |
382 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already"); | |
383 | |
384 int num_active = 0; | |
385 | |
386 _shutdown_thread = thr_cur; | |
387 _vm_exited = true; // global flag | |
388 for(JavaThread *thr = Threads::first(); thr != NULL; thr = thr->next()) | |
389 if (thr!=thr_cur && thr->thread_state() == _thread_in_native) { | |
390 ++num_active; | |
391 thr->set_terminated(JavaThread::_vm_exited); // per-thread flag | |
392 } | |
393 | |
394 return num_active; | |
395 } | |
396 | |
397 int VM_Exit::wait_for_threads_in_native_to_block() { | |
398 // VM exits at safepoint. This function must be called at the final safepoint | |
399 // to wait for threads in _thread_in_native state to be quiescent. | |
400 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already"); | |
401 | |
402 Thread * thr_cur = ThreadLocalStorage::get_thread_slow(); | |
403 Monitor timer(Mutex::leaf, "VM_Exit timer", true); | |
404 | |
405 // Compiler threads need longer wait because they can access VM data directly | |
406 // while in native. If they are active and some structures being used are | |
407 // deleted by the shutdown sequence, they will crash. On the other hand, user | |
408 // threads must go through native=>Java/VM transitions first to access VM | |
409 // data, and they will be stopped during state transition. In theory, we | |
410 // don't have to wait for user threads to be quiescent, but it's always | |
411 // better to terminate VM when current thread is the only active thread, so | |
412 // wait for user threads too. Numbers are in 10 milliseconds. | |
413 int max_wait_user_thread = 30; // at least 300 milliseconds | |
414 int max_wait_compiler_thread = 1000; // at least 10 seconds | |
415 | |
416 int max_wait = max_wait_compiler_thread; | |
417 | |
418 int attempts = 0; | |
419 while (true) { | |
420 int num_active = 0; | |
421 int num_active_compiler_thread = 0; | |
422 | |
423 for(JavaThread *thr = Threads::first(); thr != NULL; thr = thr->next()) { | |
424 if (thr!=thr_cur && thr->thread_state() == _thread_in_native) { | |
425 num_active++; | |
426 if (thr->is_Compiler_thread()) { | |
427 num_active_compiler_thread++; | |
428 } | |
429 } | |
430 } | |
431 | |
432 if (num_active == 0) { | |
433 return 0; | |
434 } else if (attempts > max_wait) { | |
435 return num_active; | |
436 } else if (num_active_compiler_thread == 0 && attempts > max_wait_user_thread) { | |
437 return num_active; | |
438 } | |
439 | |
440 attempts++; | |
441 | |
442 MutexLockerEx ml(&timer, Mutex::_no_safepoint_check_flag); | |
443 timer.wait(Mutex::_no_safepoint_check_flag, 10); | |
444 } | |
445 } | |
446 | |
447 void VM_Exit::doit() { | |
448 CompileBroker::set_should_block(); | |
449 | |
450 // Wait for a short period for threads in native to block. Any thread | |
451 // still executing native code after the wait will be stopped at | |
452 // native==>Java/VM barriers. | |
453 // Among 16276 JCK tests, 94% of them come here without any threads still | |
454 // running in native; the other 6% are quiescent within 250ms (Ultra 80). | |
455 wait_for_threads_in_native_to_block(); | |
456 | |
457 set_vm_exited(); | |
458 | |
459 // cleanup globals resources before exiting. exit_globals() currently | |
460 // cleans up outputStream resources and PerfMemory resources. | |
461 exit_globals(); | |
462 | |
463 // Check for exit hook | |
464 exit_hook_t exit_hook = Arguments::exit_hook(); | |
465 if (exit_hook != NULL) { | |
466 // exit hook should exit. | |
467 exit_hook(_exit_code); | |
468 // ... but if it didn't, we must do it here | |
469 vm_direct_exit(_exit_code); | |
470 } else { | |
471 vm_direct_exit(_exit_code); | |
472 } | |
473 } | |
474 | |
475 | |
476 void VM_Exit::wait_if_vm_exited() { | |
477 if (_vm_exited && | |
478 ThreadLocalStorage::get_thread_slow() != _shutdown_thread) { | |
479 // _vm_exited is set at safepoint, and the Threads_lock is never released | |
480 // we will block here until the process dies | |
481 Threads_lock->lock_without_safepoint_check(); | |
482 ShouldNotReachHere(); | |
483 } | |
484 } |