Mercurial > hg > truffle
comparison src/share/vm/services/management.cpp @ 6779:6af8f3562069
7196045: Possible JVM deadlock in ThreadTimesClosure when using HotspotInternal non-public API.
Reviewed-by: sspitsyn, dholmes
author | kevinw |
---|---|
date | Wed, 19 Sep 2012 15:24:32 +0100 |
parents | da91efe96a93 |
children | d8ce2825b193 fb19af007ffc |
comparison
equal
deleted
inserted
replaced
6771:45f22ba9348d | 6779:6af8f3562069 |
---|---|
1802 assert(succeed, "Setting flag should succeed"); | 1802 assert(succeed, "Setting flag should succeed"); |
1803 JVM_END | 1803 JVM_END |
1804 | 1804 |
1805 class ThreadTimesClosure: public ThreadClosure { | 1805 class ThreadTimesClosure: public ThreadClosure { |
1806 private: | 1806 private: |
1807 objArrayOop _names; | 1807 objArrayHandle _names_strings; |
1808 char **_names_chars; | |
1808 typeArrayOop _times; | 1809 typeArrayOop _times; |
1809 int _names_len; | 1810 int _names_len; |
1810 int _times_len; | 1811 int _times_len; |
1811 int _count; | 1812 int _count; |
1812 | 1813 |
1813 public: | 1814 public: |
1814 ThreadTimesClosure(objArrayOop names, typeArrayOop times); | 1815 ThreadTimesClosure(objArrayHandle names, typeArrayOop times); |
1816 ~ThreadTimesClosure(); | |
1815 virtual void do_thread(Thread* thread); | 1817 virtual void do_thread(Thread* thread); |
1818 void do_unlocked(); | |
1816 int count() { return _count; } | 1819 int count() { return _count; } |
1817 }; | 1820 }; |
1818 | 1821 |
1819 ThreadTimesClosure::ThreadTimesClosure(objArrayOop names, | 1822 ThreadTimesClosure::ThreadTimesClosure(objArrayHandle names, |
1820 typeArrayOop times) { | 1823 typeArrayOop times) { |
1821 assert(names != NULL, "names was NULL"); | 1824 assert(names() != NULL, "names was NULL"); |
1822 assert(times != NULL, "times was NULL"); | 1825 assert(times != NULL, "times was NULL"); |
1823 _names = names; | 1826 _names_strings = names; |
1824 _names_len = names->length(); | 1827 _names_len = names->length(); |
1828 _names_chars = NEW_C_HEAP_ARRAY(char*, _names_len, mtInternal); | |
1825 _times = times; | 1829 _times = times; |
1826 _times_len = times->length(); | 1830 _times_len = times->length(); |
1827 _count = 0; | 1831 _count = 0; |
1828 } | 1832 } |
1829 | 1833 |
1834 // | |
1835 // Called with Threads_lock held | |
1836 // | |
1830 void ThreadTimesClosure::do_thread(Thread* thread) { | 1837 void ThreadTimesClosure::do_thread(Thread* thread) { |
1831 Handle s; | |
1832 assert(thread != NULL, "thread was NULL"); | 1838 assert(thread != NULL, "thread was NULL"); |
1833 | 1839 |
1834 // exclude externally visible JavaThreads | 1840 // exclude externally visible JavaThreads |
1835 if (thread->is_Java_thread() && !thread->is_hidden_from_external_view()) { | 1841 if (thread->is_Java_thread() && !thread->is_hidden_from_external_view()) { |
1836 return; | 1842 return; |
1840 // skip if the result array is not big enough | 1846 // skip if the result array is not big enough |
1841 return; | 1847 return; |
1842 } | 1848 } |
1843 | 1849 |
1844 EXCEPTION_MARK; | 1850 EXCEPTION_MARK; |
1851 ResourceMark rm(THREAD); // thread->name() uses ResourceArea | |
1845 | 1852 |
1846 assert(thread->name() != NULL, "All threads should have a name"); | 1853 assert(thread->name() != NULL, "All threads should have a name"); |
1847 s = java_lang_String::create_from_str(thread->name(), CHECK); | 1854 _names_chars[_count] = strdup(thread->name()); |
1848 _names->obj_at_put(_count, s()); | |
1849 | |
1850 _times->long_at_put(_count, os::is_thread_cpu_time_supported() ? | 1855 _times->long_at_put(_count, os::is_thread_cpu_time_supported() ? |
1851 os::thread_cpu_time(thread) : -1); | 1856 os::thread_cpu_time(thread) : -1); |
1852 _count++; | 1857 _count++; |
1858 } | |
1859 | |
1860 // Called without Threads_lock, we can allocate String objects. | |
1861 void ThreadTimesClosure::do_unlocked() { | |
1862 | |
1863 EXCEPTION_MARK; | |
1864 for (int i = 0; i < _count; i++) { | |
1865 Handle s = java_lang_String::create_from_str(_names_chars[i], CHECK); | |
1866 _names_strings->obj_at_put(i, s()); | |
1867 } | |
1868 } | |
1869 | |
1870 ThreadTimesClosure::~ThreadTimesClosure() { | |
1871 for (int i = 0; i < _count; i++) { | |
1872 free(_names_chars[i]); | |
1873 } | |
1874 FREE_C_HEAP_ARRAY(char *, _names_chars, mtInternal); | |
1853 } | 1875 } |
1854 | 1876 |
1855 // Fills names with VM internal thread names and times with the corresponding | 1877 // Fills names with VM internal thread names and times with the corresponding |
1856 // CPU times. If names or times is NULL, a NullPointerException is thrown. | 1878 // CPU times. If names or times is NULL, a NullPointerException is thrown. |
1857 // If the element type of names is not String, an IllegalArgumentException is | 1879 // If the element type of names is not String, an IllegalArgumentException is |
1876 } | 1898 } |
1877 | 1899 |
1878 typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(times)); | 1900 typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(times)); |
1879 typeArrayHandle times_ah(THREAD, ta); | 1901 typeArrayHandle times_ah(THREAD, ta); |
1880 | 1902 |
1881 ThreadTimesClosure ttc(names_ah(), times_ah()); | 1903 ThreadTimesClosure ttc(names_ah, times_ah()); |
1882 { | 1904 { |
1883 MutexLockerEx ml(Threads_lock); | 1905 MutexLockerEx ml(Threads_lock); |
1884 Threads::threads_do(&ttc); | 1906 Threads::threads_do(&ttc); |
1885 } | 1907 } |
1886 | 1908 ttc.do_unlocked(); |
1887 return ttc.count(); | 1909 return ttc.count(); |
1888 JVM_END | 1910 JVM_END |
1889 | 1911 |
1890 static Handle find_deadlocks(bool object_monitors_only, TRAPS) { | 1912 static Handle find_deadlocks(bool object_monitors_only, TRAPS) { |
1891 ResourceMark rm(THREAD); | 1913 ResourceMark rm(THREAD); |