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);