comparison src/share/vm/compiler/compileBroker.cpp @ 23302:90f7b4c21cfb

thread waiting for blocking JVMCI compilation should not wait on compiler queue forever (JDK-8148507)
author Doug Simon <doug.simon@oracle.com>
date Thu, 04 Feb 2016 15:21:43 +0100
parents f41d4011035d
children 633cf7bea01d
comparison
equal deleted inserted replaced
23301:93caf66f5604 23302:90f7b4c21cfb
1722 queue->add(new_task); 1722 queue->add(new_task);
1723 return new_task; 1723 return new_task;
1724 } 1724 }
1725 1725
1726 #ifdef COMPILERJVMCI 1726 #ifdef COMPILERJVMCI
1727 // The number of milliseconds to wait before checking if the 1727 // The number of milliseconds to wait before checking if
1728 // JVMCI compiler has become blocked during compilation. 1728 // JVMCI compilation has made progress.
1729 static const long BLOCKING_JVMCI_COMPILATION_WAIT_TIMESLICE = 500; 1729 static const long JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE = 500;
1730 1730
1731 // The number of successive times the above check is allowed to 1731 // The number of JVMCI compilation progress checks that must fail
1732 // see a blocked JVMCI compiler thread before unblocking the 1732 // before unblocking a thread waiting for a blocking compilation.
1733 // thread waiting for the compilation to finish. 1733 static const int JVMCI_COMPILATION_PROGRESS_WAIT_ATTEMPTS = 5;
1734 static const int BLOCKING_JVMCI_COMPILATION_WAIT_TO_UNBLOCK_ATTEMPTS = 5;
1735 1734
1736 /** 1735 /**
1737 * Waits for a JVMCI compiler to complete a given task. This thread 1736 * Waits for a JVMCI compiler to complete a given task. This thread
1738 * waits until either the task completes or it sees the JVMCI compiler 1737 * waits until either the task completes or it sees no JVMCI compilation
1739 * thread is blocked for N consecutive milliseconds where N is 1738 * progress for N consecutive milliseconds where N is
1740 * BLOCKING_JVMCI_COMPILATION_WAIT_TIMESLICE * 1739 * JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE *
1741 * BLOCKING_JVMCI_COMPILATION_WAIT_TO_UNBLOCK_ATTEMPTS. 1740 * JVMCI_COMPILATION_PROGRESS_WAIT_ATTEMPTS.
1742 * 1741 *
1743 * @return true if this thread needs to free/recycle the task 1742 * @return true if this thread needs to free/recycle the task
1744 */ 1743 */
1745 bool CompileBroker::wait_for_jvmci_completion(CompileTask* task, JavaThread* thread) { 1744 bool CompileBroker::wait_for_jvmci_completion(AbstractCompiler* comp, CompileTask* task, JavaThread* thread) {
1746 MutexLocker waiter(task->lock(), thread); 1745 MutexLocker waiter(task->lock(), thread);
1747 int consecutively_blocked = 0; 1746 assert(comp->is_jvmci(), "must be");
1747 JVMCICompiler* jvmci = (JVMCICompiler*) comp;
1748 int progress_wait_attempts = 0;
1749 int methods_compiled = jvmci->approx_num_methods_compiled();
1748 while (!task->is_complete() && !is_compilation_disabled_forever() && 1750 while (!task->is_complete() && !is_compilation_disabled_forever() &&
1749 task->lock()->wait(!Mutex::_no_safepoint_check_flag, BLOCKING_JVMCI_COMPILATION_WAIT_TIMESLICE)) { 1751 task->lock()->wait(!Mutex::_no_safepoint_check_flag, JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE)) {
1750 CompilerThread* jvmci_compiler_thread = task->jvmci_compiler_thread(); 1752 CompilerThread* jvmci_compiler_thread = task->jvmci_compiler_thread();
1753
1754 bool progress;
1751 if (jvmci_compiler_thread != NULL) { 1755 if (jvmci_compiler_thread != NULL) {
1752 JavaThreadState state; 1756 // If the JVMCI compiler thread is not blocked, we deem it to be making progress.
1753 { 1757 progress = jvmci_compiler_thread->thread_state() != _thread_blocked;
1754 // A JVMCI compiler thread should not disappear at this point 1758 } else {
1755 // but let's be extra safe. 1759 // Still waiting on JVMCI compiler queue. This thread may be holding a lock
1756 MutexLocker mu(Threads_lock, thread); 1760 // that all JVMCI compiler threads are blocked on. We use the counter for
1757 state = jvmci_compiler_thread->thread_state(); 1761 // successful JVMCI compilations to determine whether JVMCI compilation
1758 } 1762 // is still making progress through the JVMCI compiler queue.
1759 if (state == _thread_blocked) { 1763 progress = jvmci->approx_num_methods_compiled() != methods_compiled;
1760 if (++consecutively_blocked == BLOCKING_JVMCI_COMPILATION_WAIT_TO_UNBLOCK_ATTEMPTS) { 1764 }
1761 if (PrintCompilation) { 1765
1762 task->print_compilation(tty, "wait for blocking compilation timed out"); 1766 if (!progress) {
1763 } 1767 if (++progress_wait_attempts == JVMCI_COMPILATION_PROGRESS_WAIT_ATTEMPTS) {
1764 break; 1768 if (PrintCompilation) {
1769 task->print_compilation(tty, "wait for blocking compilation timed out");
1765 } 1770 }
1766 } else { 1771 break;
1767 consecutively_blocked = 0;
1768 } 1772 }
1769 } else { 1773 } else {
1770 // Still waiting on JVMCI compiler queue 1774 progress_wait_attempts = 0;
1775 if (jvmci_compiler_thread == NULL) {
1776 methods_compiled = jvmci->approx_num_methods_compiled();
1777 }
1771 } 1778 }
1772 } 1779 }
1773 task->clear_waiter(); 1780 task->clear_waiter();
1774 return task->is_complete(); 1781 return task->is_complete();
1775 } 1782 }
1790 thread->set_blocked_on_compilation(true); 1797 thread->set_blocked_on_compilation(true);
1791 1798
1792 methodHandle method(thread, task->method()); 1799 methodHandle method(thread, task->method());
1793 bool free_task = true; 1800 bool free_task = true;
1794 #ifdef COMPILERJVMCI 1801 #ifdef COMPILERJVMCI
1795 if (compiler(task->comp_level())->is_jvmci()) { 1802 AbstractCompiler* comp = compiler(task->comp_level());
1796 free_task = wait_for_jvmci_completion(task, thread); 1803 if (comp->is_jvmci()) {
1804 free_task = wait_for_jvmci_completion(comp, task, thread);
1797 } else 1805 } else
1798 #endif 1806 #endif
1799 { 1807 {
1800 MutexLocker waiter(task->lock(), thread); 1808 MutexLocker waiter(task->lock(), thread);
1801 while (!task->is_complete() && !is_compilation_disabled_forever()) { 1809 while (!task->is_complete() && !is_compilation_disabled_forever()) {