comparison src/share/vm/compiler/compileBroker.cpp @ 22762:9d78d44d3aac

improved JVMCI support for blocking compilation (GRAAL-1387)
author Doug Simon <doug.simon@oracle.com>
date Fri, 08 Jan 2016 17:30:33 +0100
parents 24fd08e99b35
children 94b7354ef0e0
comparison
equal deleted inserted replaced
22761:f2206f5bb62e 22762:9d78d44d3aac
235 } 235 }
236 236
237 CompileTaskWrapper::CompileTaskWrapper(CompileTask* task) { 237 CompileTaskWrapper::CompileTaskWrapper(CompileTask* task) {
238 CompilerThread* thread = CompilerThread::current(); 238 CompilerThread* thread = CompilerThread::current();
239 thread->set_task(task); 239 thread->set_task(task);
240 #ifdef COMPILERJVMCI
241 if (task->is_blocking() && CompileBroker::compiler(task->comp_level())->is_jvmci()) {
242 task->set_jvmci_compiler_thread(thread);
243 }
244 #endif
240 CompileLog* log = thread->log(); 245 CompileLog* log = thread->log();
241 if (log != NULL) task->log_task_start(log); 246 if (log != NULL) task->log_task_start(log);
242 } 247 }
243 248
244 CompileTaskWrapper::~CompileTaskWrapper() { 249 CompileTaskWrapper::~CompileTaskWrapper() {
254 { 259 {
255 MutexLocker notifier(task->lock(), thread); 260 MutexLocker notifier(task->lock(), thread);
256 task->mark_complete(); 261 task->mark_complete();
257 #ifdef COMPILERJVMCI 262 #ifdef COMPILERJVMCI
258 if (CompileBroker::compiler(task->comp_level())->is_jvmci()) { 263 if (CompileBroker::compiler(task->comp_level())->is_jvmci()) {
259 // Blocking JVMCI compilations are performed with a timeout so as 264 if (!task->has_waiter()) {
260 // to avoid deadlock between an application thread and a JVMCI 265 // The waiting thread timed out and thus did not free the task.
261 // compiler thread (both of which execute Java code).
262 if (task->has_waiter()) {
263 // Notify the waiting thread that the compilation has completed
264 // and let it free the CompileTask.
265 task->lock()->notify_all();
266 } else {
267 // The waiting thread timed out did not free the task.
268 free_task = true; 266 free_task = true;
269 } 267 }
270 } else { 268 task->set_jvmci_compiler_thread(NULL);
269 }
270 #endif
271 if (!free_task) {
271 // Notify the waiting thread that the compilation has completed. 272 // Notify the waiting thread that the compilation has completed.
272 task->lock()->notify_all(); 273 task->lock()->notify_all();
273 } 274 }
274 #else
275 // Notify the waiting thread that the compilation has completed.
276 task->lock()->notify_all();
277 #endif
278 } 275 }
279 if (free_task) { 276 if (free_task) {
280 // The task can only be freed once the task lock is released. 277 // The task can only be freed once the task lock is released.
281 CompileTask::free(task); 278 CompileTask::free(task);
282 } 279 }
306 _task_free_list = task->next(); 303 _task_free_list = task->next();
307 task->set_next(NULL); 304 task->set_next(NULL);
308 } else { 305 } else {
309 task = new CompileTask(); 306 task = new CompileTask();
310 DEBUG_ONLY(_num_allocated_tasks++;) 307 DEBUG_ONLY(_num_allocated_tasks++;)
311 assert (_num_allocated_tasks < 10000, "Leaking compilation tasks?"); 308 NOT_COMPILERJVMCI(assert (_num_allocated_tasks < 10000, "Leaking compilation tasks?");)
312 task->set_next(NULL); 309 task->set_next(NULL);
313 task->set_is_free(true); 310 task->set_is_free(true);
314 } 311 }
315 assert(task->is_free(), "Task must be free."); 312 assert(task->is_free(), "Task must be free.");
316 task->set_is_free(false); 313 task->set_is_free(false);
349 _method = method(); 346 _method = method();
350 _method_holder = JNIHandles::make_global(method->method_holder()->klass_holder()); 347 _method_holder = JNIHandles::make_global(method->method_holder()->klass_holder());
351 _osr_bci = osr_bci; 348 _osr_bci = osr_bci;
352 _is_blocking = is_blocking; 349 _is_blocking = is_blocking;
353 COMPILERJVMCI_PRESENT(_has_waiter = CompileBroker::compiler(comp_level)->is_jvmci();) 350 COMPILERJVMCI_PRESENT(_has_waiter = CompileBroker::compiler(comp_level)->is_jvmci();)
351 COMPILERJVMCI_PRESENT(_jvmci_compiler_thread = NULL;)
354 _comp_level = comp_level; 352 _comp_level = comp_level;
355 _num_inlined_bytecodes = 0; 353 _num_inlined_bytecodes = 0;
356 354
357 _is_complete = false; 355 _is_complete = false;
358 _is_success = false; 356 _is_success = false;
1711 blocking); 1709 blocking);
1712 queue->add(new_task); 1710 queue->add(new_task);
1713 return new_task; 1711 return new_task;
1714 } 1712 }
1715 1713
1716 // 1 second should be long enough to complete most JVMCI compilations 1714 #ifdef COMPILERJVMCI
1717 // and not too long to stall a blocking JVMCI compilation that 1715 // The number of milliseconds to wait before checking if the
1718 // is trying to acquire a lock held by the app thread that submitted the 1716 // JVMCI compiler has become blocked during compilation.
1719 // compilation. 1717 static const long BLOCKING_JVMCI_COMPILATION_WAIT_TIMESLICE = 500;
1720 static const long BLOCKING_JVMCI_COMPILATION_TIMEOUT = 1000; 1718
1719 // The number of successive times the above check is allowed to
1720 // see a blocked JVMCI compiler thread before unblocking the
1721 // thread waiting for the compilation to finish.
1722 static const int BLOCKING_JVMCI_COMPILATION_WAIT_TO_UNBLOCK_ATTEMPTS = 5;
1723
1724 /**
1725 * Waits for a JVMCI compiler to complete a given task. This thread
1726 * waits until either the task completes or it sees the JVMCI compiler
1727 * thread is blocked for N consecutive milliseconds where N is
1728 * BLOCKING_JVMCI_COMPILATION_WAIT_TIMESLICE *
1729 * BLOCKING_JVMCI_COMPILATION_WAIT_TO_UNBLOCK_ATTEMPTS.
1730 *
1731 * @return true if this thread needs to free/recycle the task
1732 */
1733 bool CompileBroker::wait_for_jvmci_completion(CompileTask* task, JavaThread* thread) {
1734 MutexLocker waiter(task->lock(), thread);
1735 int consecutively_blocked = 0;
1736 while (task->lock()->wait(!Mutex::_no_safepoint_check_flag, BLOCKING_JVMCI_COMPILATION_WAIT_TIMESLICE)) {
1737 CompilerThread* jvmci_compiler_thread = task->jvmci_compiler_thread();
1738 if (jvmci_compiler_thread != NULL) {
1739 JavaThreadState state;
1740 {
1741 // A JVMCI compiler thread should not disappear at this point
1742 // but let's be extra safe.
1743 MutexLocker mu(Threads_lock, thread);
1744 state = jvmci_compiler_thread->thread_state();
1745 }
1746 if (state == _thread_blocked) {
1747 if (++consecutively_blocked == BLOCKING_JVMCI_COMPILATION_WAIT_TO_UNBLOCK_ATTEMPTS) {
1748 if (_compilation_log != NULL) {
1749 _compilation_log->log_failure(thread, task, "compilation timed out", NULL);
1750 }
1751 if (PrintCompilation) {
1752 task->print_compilation(tty, "compilation timed out");
1753 }
1754 break;
1755 }
1756 } else {
1757 consecutively_blocked = 0;
1758 }
1759 } else {
1760 // Still waiting on JVMCI compiler queue
1761 }
1762 }
1763 task->clear_waiter();
1764 return task->is_complete();
1765 }
1766 #endif
1721 1767
1722 /** 1768 /**
1723 * Wait for the compilation task to complete. 1769 * Wait for the compilation task to complete.
1724 */ 1770 */
1725 void CompileBroker::wait_for_completion(CompileTask* task) { 1771 void CompileBroker::wait_for_completion(CompileTask* task) {
1735 1781
1736 methodHandle method(thread, task->method()); 1782 methodHandle method(thread, task->method());
1737 bool free_task = true; 1783 bool free_task = true;
1738 #ifdef COMPILERJVMCI 1784 #ifdef COMPILERJVMCI
1739 if (compiler(task->comp_level())->is_jvmci()) { 1785 if (compiler(task->comp_level())->is_jvmci()) {
1740 { 1786 free_task = wait_for_jvmci_completion(task, thread);
1741 MutexLocker waiter(task->lock(), thread);
1742 // No need to check if compilation has completed - just
1743 // rely on the time out. The JVMCI compiler thread will
1744 // recycle the CompileTask.
1745 task->lock()->wait(!Mutex::_no_safepoint_check_flag, BLOCKING_JVMCI_COMPILATION_TIMEOUT);
1746 // If the compilation completes while has_waiter is true then
1747 // this thread is responsible for freeing the task. Otherwise
1748 // the compiler thread will free the task.
1749 task->clear_waiter();
1750 free_task = task->is_complete();
1751 }
1752 } else 1787 } else
1753 #endif 1788 #endif
1754 { 1789 {
1755 MutexLocker waiter(task->lock(), thread); 1790 MutexLocker waiter(task->lock(), thread);
1756 while (!task->is_complete() && !is_compilation_disabled_forever()) { 1791 while (!task->is_complete() && !is_compilation_disabled_forever()) {