225 } |
225 } |
226 |
226 |
227 CompileTaskWrapper::CompileTaskWrapper(CompileTask* task) { |
227 CompileTaskWrapper::CompileTaskWrapper(CompileTask* task) { |
228 CompilerThread* thread = CompilerThread::current(); |
228 CompilerThread* thread = CompilerThread::current(); |
229 thread->set_task(task); |
229 thread->set_task(task); |
|
230 #if INCLUDE_JVMCI |
|
231 if (task->is_blocking() && CompileBroker::compiler(task->comp_level())->is_jvmci()) { |
|
232 task->set_jvmci_compiler_thread(thread); |
|
233 } |
|
234 #endif |
230 CompileLog* log = thread->log(); |
235 CompileLog* log = thread->log(); |
231 if (log != NULL) task->log_task_start(log); |
236 if (log != NULL) task->log_task_start(log); |
232 } |
237 } |
233 |
238 |
234 CompileTaskWrapper::~CompileTaskWrapper() { |
239 CompileTaskWrapper::~CompileTaskWrapper() { |
243 bool free_task = false; |
248 bool free_task = false; |
244 { |
249 { |
245 MutexLocker notifier(task->lock(), thread); |
250 MutexLocker notifier(task->lock(), thread); |
246 task->mark_complete(); |
251 task->mark_complete(); |
247 #if INCLUDE_JVMCI |
252 #if INCLUDE_JVMCI |
248 if (CompileBroker::compiler(task->comp_level())->is_jvmci() && |
253 if (CompileBroker::compiler(task->comp_level())->is_jvmci()) { |
249 !task->has_waiter()) { |
254 if (!task->has_waiter()) { |
250 // The waiting thread timed out and thus did not free the task. |
255 // The waiting thread timed out and thus did not free the task. |
251 free_task = true; |
256 free_task = true; |
|
257 } |
|
258 task->set_jvmci_compiler_thread(NULL); |
252 } |
259 } |
253 #endif |
260 #endif |
254 if (!free_task) { |
261 if (!free_task) { |
255 // Notify the waiting thread that the compilation has completed |
262 // Notify the waiting thread that the compilation has completed |
256 // so that it can free the task. |
263 // so that it can free the task. |
1330 blocking); |
1337 blocking); |
1331 queue->add(new_task); |
1338 queue->add(new_task); |
1332 return new_task; |
1339 return new_task; |
1333 } |
1340 } |
1334 |
1341 |
1335 // 1 second should be long enough to complete most JVMCI compilations |
1342 #if INCLUDE_JVMCI |
1336 // and not too long to stall a blocking JVMCI compilation that |
1343 // The number of milliseconds to wait before checking if the |
1337 // is trying to acquire a lock held by the app thread that submitted the |
1344 // JVMCI compiler thread is blocked. |
1338 // compilation. |
1345 static const long BLOCKING_JVMCI_COMPILATION_WAIT_TIMESLICE = 500; |
1339 static const long BLOCKING_JVMCI_COMPILATION_TIMEOUT = 1000; |
1346 |
|
1347 // The number of successive times the above check is allowed to |
|
1348 // see a blocked JVMCI compiler thread before unblocking the |
|
1349 // thread waiting for the compilation to finish. |
|
1350 static const int BLOCKING_JVMCI_COMPILATION_WAIT_TO_UNBLOCK_ATTEMPTS = 5; |
|
1351 |
|
1352 /** |
|
1353 * Waits for a JVMCI compiler to complete a given task. This thread |
|
1354 * waits until either the task completes or it sees the JVMCI compiler |
|
1355 * thread is blocked for N consecutive milliseconds where N is |
|
1356 * BLOCKING_JVMCI_COMPILATION_WAIT_TIMESLICE * |
|
1357 * BLOCKING_JVMCI_COMPILATION_WAIT_TO_UNBLOCK_ATTEMPTS. |
|
1358 * |
|
1359 * @return true if this thread needs to free/recycle the task |
|
1360 */ |
|
1361 bool CompileBroker::wait_for_jvmci_completion(CompileTask* task, JavaThread* thread) { |
|
1362 MutexLocker waiter(task->lock(), thread); |
|
1363 int consecutively_blocked = 0; |
|
1364 while (task->lock()->wait(!Mutex::_no_safepoint_check_flag, BLOCKING_JVMCI_COMPILATION_WAIT_TIMESLICE)) { |
|
1365 CompilerThread* jvmci_compiler_thread = task->jvmci_compiler_thread(); |
|
1366 if (jvmci_compiler_thread != NULL) { |
|
1367 JavaThreadState state; |
|
1368 { |
|
1369 // A JVMCI compiler thread should not disappear at this point |
|
1370 // but let's be extra safe. |
|
1371 MutexLocker mu(Threads_lock, thread); |
|
1372 state = jvmci_compiler_thread->thread_state(); |
|
1373 } |
|
1374 if (state == _thread_blocked) { |
|
1375 if (++consecutively_blocked == BLOCKING_JVMCI_COMPILATION_WAIT_TO_UNBLOCK_ATTEMPTS) { |
|
1376 if (PrintCompilation) { |
|
1377 task->print(tty, "wait for blocking compilation timed out"); |
|
1378 } |
|
1379 break; |
|
1380 } |
|
1381 } else { |
|
1382 consecutively_blocked = 0; |
|
1383 } |
|
1384 } else { |
|
1385 // Still waiting on JVMCI compiler queue |
|
1386 } |
|
1387 } |
|
1388 task->clear_waiter(); |
|
1389 return task->is_complete(); |
|
1390 } |
|
1391 #endif |
1340 |
1392 |
1341 /** |
1393 /** |
1342 * Wait for the compilation task to complete. |
1394 * Wait for the compilation task to complete. |
1343 */ |
1395 */ |
1344 void CompileBroker::wait_for_completion(CompileTask* task) { |
1396 void CompileBroker::wait_for_completion(CompileTask* task) { |
1354 |
1406 |
1355 methodHandle method(thread, task->method()); |
1407 methodHandle method(thread, task->method()); |
1356 bool free_task; |
1408 bool free_task; |
1357 #if INCLUDE_JVMCI |
1409 #if INCLUDE_JVMCI |
1358 if (compiler(task->comp_level())->is_jvmci()) { |
1410 if (compiler(task->comp_level())->is_jvmci()) { |
1359 MutexLocker waiter(task->lock(), thread); |
1411 free_task = wait_for_jvmci_completion(task, thread); |
1360 // No need to check if compilation has completed - just |
|
1361 // rely on the time out. The JVMCI compiler thread will |
|
1362 // recycle the CompileTask. |
|
1363 task->lock()->wait(!Mutex::_no_safepoint_check_flag, BLOCKING_JVMCI_COMPILATION_TIMEOUT); |
|
1364 // If the compilation completes while has_waiter is true then |
|
1365 // this thread is responsible for freeing the task. Otherwise |
|
1366 // the compiler thread will free the task. |
|
1367 task->clear_waiter(); |
|
1368 free_task = task->is_complete(); |
|
1369 } else |
1412 } else |
1370 #endif |
1413 #endif |
1371 { |
1414 { |
1372 MutexLocker waiter(task->lock(), thread); |
1415 MutexLocker waiter(task->lock(), thread); |
1373 free_task = true; |
1416 free_task = true; |
1753 |
1796 |
1754 // Allocate a new set of JNI handles. |
1797 // Allocate a new set of JNI handles. |
1755 push_jni_handle_block(); |
1798 push_jni_handle_block(); |
1756 Method* target_handle = task->method(); |
1799 Method* target_handle = task->method(); |
1757 int compilable = ciEnv::MethodCompilable; |
1800 int compilable = ciEnv::MethodCompilable; |
|
1801 const char* failure_reason = NULL; |
|
1802 const char* retry_message = NULL; |
1758 AbstractCompiler *comp = compiler(task_level); |
1803 AbstractCompiler *comp = compiler(task_level); |
1759 |
1804 |
1760 int system_dictionary_modification_counter; |
1805 int system_dictionary_modification_counter; |
1761 { |
1806 { |
1762 MutexLocker locker(Compile_lock, thread); |
1807 MutexLocker locker(Compile_lock, thread); |
1772 JVMCIEnv env(task, system_dictionary_modification_counter); |
1817 JVMCIEnv env(task, system_dictionary_modification_counter); |
1773 methodHandle method(thread, target_handle); |
1818 methodHandle method(thread, target_handle); |
1774 jvmci->compile_method(method, osr_bci, &env); |
1819 jvmci->compile_method(method, osr_bci, &env); |
1775 |
1820 |
1776 post_compile(thread, task, event, task->code() != NULL, NULL); |
1821 post_compile(thread, task, event, task->code() != NULL, NULL); |
|
1822 |
|
1823 failure_reason = env.failure_reason(); |
|
1824 if (!env.retryable()) { |
|
1825 retry_message = "not retryable"; |
|
1826 compilable = ciEnv::MethodCompilable_not_at_tier; |
|
1827 } |
|
1828 |
1777 } else |
1829 } else |
1778 #endif // INCLUDE_JVMCI |
1830 #endif // INCLUDE_JVMCI |
1779 { |
1831 { |
1780 |
|
1781 NoHandleMark nhm; |
1832 NoHandleMark nhm; |
1782 ThreadToNativeFromVM ttn(thread); |
1833 ThreadToNativeFromVM ttn(thread); |
1783 |
1834 |
1784 ciEnv ci_env(task, system_dictionary_modification_counter); |
1835 ciEnv ci_env(task, system_dictionary_modification_counter); |
1785 if (should_break) { |
1836 if (should_break) { |
1823 |
1874 |
1824 // Copy this bit to the enclosing block: |
1875 // Copy this bit to the enclosing block: |
1825 compilable = ci_env.compilable(); |
1876 compilable = ci_env.compilable(); |
1826 |
1877 |
1827 if (ci_env.failing()) { |
1878 if (ci_env.failing()) { |
1828 task->set_failure_reason(ci_env.failure_reason()); |
1879 failure_reason = ci_env.failure_reason(); |
1829 ci_env.report_failure(ci_env.failure_reason()); |
1880 retry_message = ci_env.retry_message(); |
1830 const char* retry_message = ci_env.retry_message(); |
1881 ci_env.report_failure(failure_reason); |
1831 if (_compilation_log != NULL) { |
|
1832 _compilation_log->log_failure(thread, task, ci_env.failure_reason(), retry_message); |
|
1833 } |
|
1834 if (PrintCompilation) { |
|
1835 FormatBufferResource msg = retry_message != NULL ? |
|
1836 FormatBufferResource("COMPILE SKIPPED: %s (%s)", ci_env.failure_reason(), retry_message) : |
|
1837 FormatBufferResource("COMPILE SKIPPED: %s", ci_env.failure_reason()); |
|
1838 task->print(tty, msg); |
|
1839 } |
|
1840 } |
1882 } |
1841 |
1883 |
1842 post_compile(thread, task, event, !ci_env.failing(), &ci_env); |
1884 post_compile(thread, task, event, !ci_env.failing(), &ci_env); |
1843 } |
1885 } |
|
1886 // Remove the JNI handle block after the ciEnv destructor has run in |
|
1887 // the previous block. |
|
1888 pop_jni_handle_block(); |
|
1889 |
|
1890 if (failure_reason != NULL) { |
|
1891 task->set_failure_reason(failure_reason); |
|
1892 if (_compilation_log != NULL) { |
|
1893 _compilation_log->log_failure(thread, task, failure_reason, retry_message); |
|
1894 } |
|
1895 if (PrintCompilation) { |
|
1896 FormatBufferResource msg = retry_message != NULL ? |
|
1897 FormatBufferResource("COMPILE SKIPPED: %s (%s)", failure_reason, retry_message) : |
|
1898 FormatBufferResource("COMPILE SKIPPED: %s", failure_reason); |
|
1899 task->print(tty, msg); |
|
1900 } |
|
1901 } |
|
1902 |
|
1903 methodHandle method(thread, task->method()); |
|
1904 |
|
1905 DTRACE_METHOD_COMPILE_END_PROBE(method, compiler_name(task_level), task->is_success()); |
|
1906 |
|
1907 collect_statistics(thread, time, task); |
|
1908 |
|
1909 bool printnmethods = directive->PrintAssemblyOption || directive->PrintNMethodsOption; |
|
1910 if (printnmethods || PrintDebugInfo || PrintRelocations || PrintDependencies || PrintExceptionHandlers) { |
|
1911 nmethod* nm = task->code(); |
|
1912 if (nm != NULL) { |
|
1913 nm->print_nmethod(printnmethods); |
|
1914 } |
|
1915 } |
1844 DirectivesStack::release(directive); |
1916 DirectivesStack::release(directive); |
1845 pop_jni_handle_block(); |
|
1846 |
|
1847 methodHandle method(thread, task->method()); |
|
1848 |
|
1849 DTRACE_METHOD_COMPILE_END_PROBE(method, compiler_name(task_level), task->is_success()); |
|
1850 |
|
1851 collect_statistics(thread, time, task); |
|
1852 |
1917 |
1853 if (PrintCompilation && PrintCompilation2) { |
1918 if (PrintCompilation && PrintCompilation2) { |
1854 tty->print("%7d ", (int) tty->time_stamp().milliseconds()); // print timestamp |
1919 tty->print("%7d ", (int) tty->time_stamp().milliseconds()); // print timestamp |
1855 tty->print("%4d ", compile_id); // print compilation number |
1920 tty->print("%4d ", compile_id); // print compilation number |
1856 tty->print("%s ", (is_osr ? "%" : " ")); |
1921 tty->print("%s ", (is_osr ? "%" : " ")); |