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