21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/symbolTable.hpp"
27 #include "classfile/vmSymbols.hpp"
28 #include "code/codeCache.hpp"
29 #include "compiler/compileBroker.hpp"
30 #include "gc/shared/isGCActiveMark.hpp"
31 #include "logging/log.hpp"
32 #include "logging/logStream.hpp"
33 #include "memory/heapInspection.hpp"
34 #include "memory/resourceArea.hpp"
35 #include "oops/symbol.hpp"
36 #include "runtime/arguments.hpp"
37 #include "runtime/deoptimization.hpp"
38 #include "runtime/interfaceSupport.hpp"
39 #include "runtime/sweeper.hpp"
40 #include "runtime/thread.inline.hpp"
41 #include "runtime/vm_operations.hpp"
42 #include "services/threadService.hpp"
43 #include "trace/tracing.hpp"
44
45 #define VM_OP_NAME_INITIALIZE(name) #name,
46
47 const char* VM_Operation::_names[VM_Operation::VMOp_Terminating] = \
48 { VM_OPS_DO(VM_OP_NAME_INITIALIZE) };
49
50 void VM_Operation::set_calling_thread(Thread* thread, ThreadPriority priority) {
51 _calling_thread = thread;
52 assert(MinPriority <= priority && priority <= MaxPriority, "sanity check");
53 _priority = priority;
54 }
55
56
57 void VM_Operation::evaluate() {
58 ResourceMark rm;
59 LogTarget(Debug, vmoperation) lt;
60 if (lt.is_enabled()) {
79 case _concurrent : return "concurrent";
80 case _async_safepoint: return "async safepoint";
81 default : return "unknown";
82 }
83 }
84 // Called by fatal error handler.
85 void VM_Operation::print_on_error(outputStream* st) const {
86 st->print("VM_Operation (" PTR_FORMAT "): ", p2i(this));
87 st->print("%s", name());
88
89 const char* mode = mode_to_string(evaluation_mode());
90 st->print(", mode: %s", mode);
91
92 if (calling_thread()) {
93 st->print(", requested by thread " PTR_FORMAT, p2i(calling_thread()));
94 }
95 }
96
97 void VM_ThreadStop::doit() {
98 assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
99 JavaThread* target = java_lang_Thread::thread(target_thread());
100 // Note that this now allows multiple ThreadDeath exceptions to be
101 // thrown at a thread.
102 if (target != NULL) {
103 // the thread has run and is not already in the process of exiting
104 target->send_thread_stop(throwable());
105 }
106 }
107
108 void VM_ClearICs::doit() {
109 if (_preserve_static_stubs) {
110 CodeCache::cleanup_inline_caches();
111 } else {
112 CodeCache::clear_inline_caches();
113 }
114 }
115
116 void VM_Deoptimize::doit() {
117 // We do not want any GCs to happen while we are in the middle of this VM operation
118 ResourceMark rm;
119 DeoptimizationMarker dm;
120
121 // Deoptimize all activations depending on marked nmethods
122 Deoptimization::deoptimize_dependents();
123
129 NMethodSweeper::mark_active_nmethods();
130 }
131
132 VM_DeoptimizeFrame::VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id, int reason) {
133 _thread = thread;
134 _id = id;
135 _reason = reason;
136 }
137
138
139 void VM_DeoptimizeFrame::doit() {
140 assert(_reason > Deoptimization::Reason_none && _reason < Deoptimization::Reason_LIMIT, "invalid deopt reason");
141 Deoptimization::deoptimize_frame_internal(_thread, _id, (Deoptimization::DeoptReason)_reason);
142 }
143
144
145 #ifndef PRODUCT
146
147 void VM_DeoptimizeAll::doit() {
148 DeoptimizationMarker dm;
149 // deoptimize all java threads in the system
150 if (DeoptimizeALot) {
151 for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) {
152 if (thread->has_last_Java_frame()) {
153 thread->deoptimize();
154 }
155 }
156 } else if (DeoptimizeRandom) {
157
158 // Deoptimize some selected threads and frames
159 int tnum = os::random() & 0x3;
160 int fnum = os::random() & 0x3;
161 int tcount = 0;
162 for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) {
163 if (thread->has_last_Java_frame()) {
164 if (tcount++ == tnum) {
165 tcount = 0;
166 int fcount = 0;
167 // Deoptimize some selected frames.
168 // Biased llocking wants a updated register map
169 for(StackFrameStream fst(thread, UseBiasedLocking); !fst.is_done(); fst.next()) {
170 if (fst.current()->can_be_deoptimized()) {
171 if (fcount++ == fnum) {
172 fcount = 0;
173 Deoptimization::deoptimize(thread, *fst.current(), fst.register_map());
174 }
175 }
176 }
177 }
178 }
179 }
180 }
181 }
182
242 cycle = cycle->next();
243 delete d;
244 }
245 }
246 }
247
248 bool VM_FindDeadlocks::doit_prologue() {
249 if (_concurrent_locks) {
250 // Make sure AbstractOwnableSynchronizer is loaded
251 JavaThread* jt = JavaThread::current();
252 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(jt);
253 if (jt->has_pending_exception()) {
254 return false;
255 }
256 }
257
258 return true;
259 }
260
261 void VM_FindDeadlocks::doit() {
262 _deadlocks = ThreadService::find_deadlocks_at_safepoint(_concurrent_locks);
263 if (_out != NULL) {
264 int num_deadlocks = 0;
265 for (DeadlockCycle* cycle = _deadlocks; cycle != NULL; cycle = cycle->next()) {
266 num_deadlocks++;
267 cycle->print_on(_out);
268 }
269
270 if (num_deadlocks == 1) {
271 _out->print_cr("\nFound 1 deadlock.\n");
272 _out->flush();
273 } else if (num_deadlocks > 1) {
274 _out->print_cr("\nFound %d deadlocks.\n", num_deadlocks);
275 _out->flush();
276 }
277 }
278 }
279
280 VM_ThreadDump::VM_ThreadDump(ThreadDumpResult* result,
281 int max_depth,
282 bool with_locked_monitors,
283 bool with_locked_synchronizers) {
284 _result = result;
285 _num_threads = 0; // 0 indicates all threads
286 _threads = NULL;
287 _result = result;
314 }
315
316 if (_with_locked_synchronizers) {
317 // Acquire Heap_lock to dump concurrent locks
318 Heap_lock->lock();
319 }
320
321 return true;
322 }
323
324 void VM_ThreadDump::doit_epilogue() {
325 if (_with_locked_synchronizers) {
326 // Release Heap_lock
327 Heap_lock->unlock();
328 }
329 }
330
331 void VM_ThreadDump::doit() {
332 ResourceMark rm;
333
334 ConcurrentLocksDump concurrent_locks(true);
335 if (_with_locked_synchronizers) {
336 concurrent_locks.dump_at_safepoint();
337 }
338
339 if (_num_threads == 0) {
340 // Snapshot all live threads
341 for (JavaThread* jt = Threads::first(); jt != NULL; jt = jt->next()) {
342 if (jt->is_exiting() ||
343 jt->is_hidden_from_external_view()) {
344 // skip terminating threads and hidden threads
345 continue;
346 }
347 ThreadConcurrentLocks* tcl = NULL;
348 if (_with_locked_synchronizers) {
349 tcl = concurrent_locks.thread_concurrent_locks(jt);
350 }
351 ThreadSnapshot* ts = snapshot_thread(jt, tcl);
352 _result->add_thread_snapshot(ts);
353 }
354 } else {
355 // Snapshot threads in the given _threads array
356 // A dummy snapshot is created if a thread doesn't exist
357 for (int i = 0; i < _num_threads; i++) {
358 instanceHandle th = _threads->at(i);
359 if (th() == NULL) {
360 // skip if the thread doesn't exist
361 // Add a dummy snapshot
362 _result->add_thread_snapshot(new ThreadSnapshot());
363 continue;
364 }
365
366 // Dump thread stack only if the thread is alive and not exiting
367 // and not VM internal thread.
368 JavaThread* jt = java_lang_Thread::thread(th());
369 if (jt == NULL || /* thread not alive */
370 jt->is_exiting() ||
371 jt->is_hidden_from_external_view()) {
372 // add a NULL snapshot if skipped
373 _result->add_thread_snapshot(new ThreadSnapshot());
374 continue;
375 }
376 ThreadConcurrentLocks* tcl = NULL;
377 if (_with_locked_synchronizers) {
378 tcl = concurrent_locks.thread_concurrent_locks(jt);
379 }
380 ThreadSnapshot* ts = snapshot_thread(jt, tcl);
381 _result->add_thread_snapshot(ts);
382 }
383 }
384 }
385
386 ThreadSnapshot* VM_ThreadDump::snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl) {
387 ThreadSnapshot* snapshot = new ThreadSnapshot(java_thread);
388 snapshot->dump_stack_at_safepoint(_max_depth, _with_locked_monitors);
389 snapshot->set_concurrent_locks(tcl);
390 return snapshot;
391 }
392
393 volatile bool VM_Exit::_vm_exited = false;
394 Thread * VM_Exit::_shutdown_thread = NULL;
395
396 int VM_Exit::set_vm_exited() {
397
398 Thread * thr_cur = Thread::current();
399
400 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already");
401
402 int num_active = 0;
403
404 _shutdown_thread = thr_cur;
405 _vm_exited = true; // global flag
406 for(JavaThread *thr = Threads::first(); thr != NULL; thr = thr->next())
407 if (thr!=thr_cur && thr->thread_state() == _thread_in_native) {
408 ++num_active;
409 thr->set_terminated(JavaThread::_vm_exited); // per-thread flag
410 }
411
412 return num_active;
413 }
414
415 int VM_Exit::wait_for_threads_in_native_to_block() {
416 // VM exits at safepoint. This function must be called at the final safepoint
417 // to wait for threads in _thread_in_native state to be quiescent.
418 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already");
419
420 Thread * thr_cur = Thread::current();
421 Monitor timer(Mutex::leaf, "VM_Exit timer", true,
422 Monitor::_safepoint_check_never);
423
424 // Compiler threads need longer wait because they can access VM data directly
425 // while in native. If they are active and some structures being used are
426 // deleted by the shutdown sequence, they will crash. On the other hand, user
427 // threads must go through native=>Java/VM transitions first to access VM
428 // data, and they will be stopped during state transition. In theory, we
429 // don't have to wait for user threads to be quiescent, but it's always
430 // better to terminate VM when current thread is the only active thread, so
431 // wait for user threads too. Numbers are in 10 milliseconds.
432 int max_wait_user_thread = 30; // at least 300 milliseconds
433 int max_wait_compiler_thread = 1000; // at least 10 seconds
434
435 int max_wait = max_wait_compiler_thread;
436
437 int attempts = 0;
438 while (true) {
439 int num_active = 0;
440 int num_active_compiler_thread = 0;
441
442 for(JavaThread *thr = Threads::first(); thr != NULL; thr = thr->next()) {
443 if (thr!=thr_cur && thr->thread_state() == _thread_in_native) {
444 num_active++;
445 if (thr->is_Compiler_thread()) {
446 num_active_compiler_thread++;
447 }
448 }
449 }
450
451 if (num_active == 0) {
452 return 0;
453 } else if (attempts > max_wait) {
454 return num_active;
455 } else if (num_active_compiler_thread == 0 && attempts > max_wait_user_thread) {
456 return num_active;
457 }
458
459 attempts++;
460
461 MutexLockerEx ml(&timer, Mutex::_no_safepoint_check_flag);
462 timer.wait(Mutex::_no_safepoint_check_flag, 10);
|
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/symbolTable.hpp"
27 #include "classfile/vmSymbols.hpp"
28 #include "code/codeCache.hpp"
29 #include "compiler/compileBroker.hpp"
30 #include "gc/shared/isGCActiveMark.hpp"
31 #include "logging/log.hpp"
32 #include "logging/logStream.hpp"
33 #include "memory/heapInspection.hpp"
34 #include "memory/resourceArea.hpp"
35 #include "oops/symbol.hpp"
36 #include "runtime/arguments.hpp"
37 #include "runtime/deoptimization.hpp"
38 #include "runtime/interfaceSupport.hpp"
39 #include "runtime/sweeper.hpp"
40 #include "runtime/thread.inline.hpp"
41 #include "runtime/threadSMR.inline.hpp"
42 #include "runtime/vm_operations.hpp"
43 #include "services/threadService.hpp"
44 #include "trace/tracing.hpp"
45
46 #define VM_OP_NAME_INITIALIZE(name) #name,
47
48 const char* VM_Operation::_names[VM_Operation::VMOp_Terminating] = \
49 { VM_OPS_DO(VM_OP_NAME_INITIALIZE) };
50
51 void VM_Operation::set_calling_thread(Thread* thread, ThreadPriority priority) {
52 _calling_thread = thread;
53 assert(MinPriority <= priority && priority <= MaxPriority, "sanity check");
54 _priority = priority;
55 }
56
57
58 void VM_Operation::evaluate() {
59 ResourceMark rm;
60 LogTarget(Debug, vmoperation) lt;
61 if (lt.is_enabled()) {
80 case _concurrent : return "concurrent";
81 case _async_safepoint: return "async safepoint";
82 default : return "unknown";
83 }
84 }
85 // Called by fatal error handler.
86 void VM_Operation::print_on_error(outputStream* st) const {
87 st->print("VM_Operation (" PTR_FORMAT "): ", p2i(this));
88 st->print("%s", name());
89
90 const char* mode = mode_to_string(evaluation_mode());
91 st->print(", mode: %s", mode);
92
93 if (calling_thread()) {
94 st->print(", requested by thread " PTR_FORMAT, p2i(calling_thread()));
95 }
96 }
97
98 void VM_ThreadStop::doit() {
99 assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
100 ThreadsListHandle tlh;
101 JavaThread* target = java_lang_Thread::thread(target_thread());
102 // Note that this now allows multiple ThreadDeath exceptions to be
103 // thrown at a thread.
104 if (target != NULL && (!EnableThreadSMRExtraValidityChecks || tlh.includes(target))) {
105 // The target thread has run and has not exited yet.
106 target->send_thread_stop(throwable());
107 }
108 }
109
110 void VM_ClearICs::doit() {
111 if (_preserve_static_stubs) {
112 CodeCache::cleanup_inline_caches();
113 } else {
114 CodeCache::clear_inline_caches();
115 }
116 }
117
118 void VM_Deoptimize::doit() {
119 // We do not want any GCs to happen while we are in the middle of this VM operation
120 ResourceMark rm;
121 DeoptimizationMarker dm;
122
123 // Deoptimize all activations depending on marked nmethods
124 Deoptimization::deoptimize_dependents();
125
131 NMethodSweeper::mark_active_nmethods();
132 }
133
134 VM_DeoptimizeFrame::VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id, int reason) {
135 _thread = thread;
136 _id = id;
137 _reason = reason;
138 }
139
140
141 void VM_DeoptimizeFrame::doit() {
142 assert(_reason > Deoptimization::Reason_none && _reason < Deoptimization::Reason_LIMIT, "invalid deopt reason");
143 Deoptimization::deoptimize_frame_internal(_thread, _id, (Deoptimization::DeoptReason)_reason);
144 }
145
146
147 #ifndef PRODUCT
148
149 void VM_DeoptimizeAll::doit() {
150 DeoptimizationMarker dm;
151 JavaThreadIteratorWithHandle jtiwh;
152 // deoptimize all java threads in the system
153 if (DeoptimizeALot) {
154 for (; JavaThread *thread = jtiwh.next(); ) {
155 if (thread->has_last_Java_frame()) {
156 thread->deoptimize();
157 }
158 }
159 } else if (DeoptimizeRandom) {
160
161 // Deoptimize some selected threads and frames
162 int tnum = os::random() & 0x3;
163 int fnum = os::random() & 0x3;
164 int tcount = 0;
165 for (; JavaThread *thread = jtiwh.next(); ) {
166 if (thread->has_last_Java_frame()) {
167 if (tcount++ == tnum) {
168 tcount = 0;
169 int fcount = 0;
170 // Deoptimize some selected frames.
171 // Biased llocking wants a updated register map
172 for(StackFrameStream fst(thread, UseBiasedLocking); !fst.is_done(); fst.next()) {
173 if (fst.current()->can_be_deoptimized()) {
174 if (fcount++ == fnum) {
175 fcount = 0;
176 Deoptimization::deoptimize(thread, *fst.current(), fst.register_map());
177 }
178 }
179 }
180 }
181 }
182 }
183 }
184 }
185
245 cycle = cycle->next();
246 delete d;
247 }
248 }
249 }
250
251 bool VM_FindDeadlocks::doit_prologue() {
252 if (_concurrent_locks) {
253 // Make sure AbstractOwnableSynchronizer is loaded
254 JavaThread* jt = JavaThread::current();
255 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(jt);
256 if (jt->has_pending_exception()) {
257 return false;
258 }
259 }
260
261 return true;
262 }
263
264 void VM_FindDeadlocks::doit() {
265 // Update the hazard ptr in the originating thread to the current
266 // list of threads. This VM operation needs the current list of
267 // threads for proper deadlock detection and those are the
268 // JavaThreads we need to be protected when we return info to the
269 // originating thread.
270 _setter.set();
271
272 _deadlocks = ThreadService::find_deadlocks_at_safepoint(_setter.list(), _concurrent_locks);
273 if (_out != NULL) {
274 int num_deadlocks = 0;
275 for (DeadlockCycle* cycle = _deadlocks; cycle != NULL; cycle = cycle->next()) {
276 num_deadlocks++;
277 cycle->print_on_with(_setter.list(), _out);
278 }
279
280 if (num_deadlocks == 1) {
281 _out->print_cr("\nFound 1 deadlock.\n");
282 _out->flush();
283 } else if (num_deadlocks > 1) {
284 _out->print_cr("\nFound %d deadlocks.\n", num_deadlocks);
285 _out->flush();
286 }
287 }
288 }
289
290 VM_ThreadDump::VM_ThreadDump(ThreadDumpResult* result,
291 int max_depth,
292 bool with_locked_monitors,
293 bool with_locked_synchronizers) {
294 _result = result;
295 _num_threads = 0; // 0 indicates all threads
296 _threads = NULL;
297 _result = result;
324 }
325
326 if (_with_locked_synchronizers) {
327 // Acquire Heap_lock to dump concurrent locks
328 Heap_lock->lock();
329 }
330
331 return true;
332 }
333
334 void VM_ThreadDump::doit_epilogue() {
335 if (_with_locked_synchronizers) {
336 // Release Heap_lock
337 Heap_lock->unlock();
338 }
339 }
340
341 void VM_ThreadDump::doit() {
342 ResourceMark rm;
343
344 // Set the hazard ptr in the originating thread to protect the
345 // current list of threads. This VM operation needs the current list
346 // of threads for a proper dump and those are the JavaThreads we need
347 // to be protected when we return info to the originating thread.
348 _result->set_t_list();
349
350 ConcurrentLocksDump concurrent_locks(true);
351 if (_with_locked_synchronizers) {
352 concurrent_locks.dump_at_safepoint();
353 }
354
355 if (_num_threads == 0) {
356 // Snapshot all live threads
357
358 for (uint i = 0; i < _result->t_list()->length(); i++) {
359 JavaThread* jt = _result->t_list()->thread_at(i);
360 if (jt->is_exiting() ||
361 jt->is_hidden_from_external_view()) {
362 // skip terminating threads and hidden threads
363 continue;
364 }
365 ThreadConcurrentLocks* tcl = NULL;
366 if (_with_locked_synchronizers) {
367 tcl = concurrent_locks.thread_concurrent_locks(jt);
368 }
369 ThreadSnapshot* ts = snapshot_thread(jt, tcl);
370 _result->add_thread_snapshot(ts);
371 }
372 } else {
373 // Snapshot threads in the given _threads array
374 // A dummy snapshot is created if a thread doesn't exist
375
376 for (int i = 0; i < _num_threads; i++) {
377 instanceHandle th = _threads->at(i);
378 if (th() == NULL) {
379 // skip if the thread doesn't exist
380 // Add a dummy snapshot
381 _result->add_thread_snapshot(new ThreadSnapshot());
382 continue;
383 }
384
385 // Dump thread stack only if the thread is alive and not exiting
386 // and not VM internal thread.
387 JavaThread* jt = java_lang_Thread::thread(th());
388 if (jt != NULL && !_result->t_list()->includes(jt)) {
389 // _threads[i] doesn't refer to a valid JavaThread; this check
390 // is primarily for JVM_DumpThreads() which doesn't have a good
391 // way to validate the _threads array.
392 jt = NULL;
393 }
394 if (jt == NULL || /* thread not alive */
395 jt->is_exiting() ||
396 jt->is_hidden_from_external_view()) {
397 // add a NULL snapshot if skipped
398 _result->add_thread_snapshot(new ThreadSnapshot());
399 continue;
400 }
401 ThreadConcurrentLocks* tcl = NULL;
402 if (_with_locked_synchronizers) {
403 tcl = concurrent_locks.thread_concurrent_locks(jt);
404 }
405 ThreadSnapshot* ts = snapshot_thread(jt, tcl);
406 _result->add_thread_snapshot(ts);
407 }
408 }
409 }
410
411 ThreadSnapshot* VM_ThreadDump::snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl) {
412 ThreadSnapshot* snapshot = new ThreadSnapshot(_result->t_list(), java_thread);
413 snapshot->dump_stack_at_safepoint(_max_depth, _with_locked_monitors);
414 snapshot->set_concurrent_locks(tcl);
415 return snapshot;
416 }
417
418 volatile bool VM_Exit::_vm_exited = false;
419 Thread * VM_Exit::_shutdown_thread = NULL;
420
421 int VM_Exit::set_vm_exited() {
422
423 Thread * thr_cur = Thread::current();
424
425 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already");
426
427 int num_active = 0;
428
429 _shutdown_thread = thr_cur;
430 _vm_exited = true; // global flag
431 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
432 if (thr!=thr_cur && thr->thread_state() == _thread_in_native) {
433 ++num_active;
434 thr->set_terminated(JavaThread::_vm_exited); // per-thread flag
435 }
436 }
437
438 return num_active;
439 }
440
441 int VM_Exit::wait_for_threads_in_native_to_block() {
442 // VM exits at safepoint. This function must be called at the final safepoint
443 // to wait for threads in _thread_in_native state to be quiescent.
444 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already");
445
446 Thread * thr_cur = Thread::current();
447 Monitor timer(Mutex::leaf, "VM_Exit timer", true,
448 Monitor::_safepoint_check_never);
449
450 // Compiler threads need longer wait because they can access VM data directly
451 // while in native. If they are active and some structures being used are
452 // deleted by the shutdown sequence, they will crash. On the other hand, user
453 // threads must go through native=>Java/VM transitions first to access VM
454 // data, and they will be stopped during state transition. In theory, we
455 // don't have to wait for user threads to be quiescent, but it's always
456 // better to terminate VM when current thread is the only active thread, so
457 // wait for user threads too. Numbers are in 10 milliseconds.
458 int max_wait_user_thread = 30; // at least 300 milliseconds
459 int max_wait_compiler_thread = 1000; // at least 10 seconds
460
461 int max_wait = max_wait_compiler_thread;
462
463 int attempts = 0;
464 JavaThreadIteratorWithHandle jtiwh;
465 while (true) {
466 int num_active = 0;
467 int num_active_compiler_thread = 0;
468
469 jtiwh.rewind();
470 for (; JavaThread *thr = jtiwh.next(); ) {
471 if (thr!=thr_cur && thr->thread_state() == _thread_in_native) {
472 num_active++;
473 if (thr->is_Compiler_thread()) {
474 num_active_compiler_thread++;
475 }
476 }
477 }
478
479 if (num_active == 0) {
480 return 0;
481 } else if (attempts > max_wait) {
482 return num_active;
483 } else if (num_active_compiler_thread == 0 && attempts > max_wait_user_thread) {
484 return num_active;
485 }
486
487 attempts++;
488
489 MutexLockerEx ml(&timer, Mutex::_no_safepoint_check_flag);
490 timer.wait(Mutex::_no_safepoint_check_flag, 10);
|