1.1 --- a/src/share/vm/services/management.cpp Tue Sep 18 11:37:26 2012 -0700 1.2 +++ b/src/share/vm/services/management.cpp Wed Sep 19 15:24:32 2012 +0100 1.3 @@ -1804,31 +1804,37 @@ 1.4 1.5 class ThreadTimesClosure: public ThreadClosure { 1.6 private: 1.7 - objArrayOop _names; 1.8 + objArrayHandle _names_strings; 1.9 + char **_names_chars; 1.10 typeArrayOop _times; 1.11 int _names_len; 1.12 int _times_len; 1.13 int _count; 1.14 1.15 public: 1.16 - ThreadTimesClosure(objArrayOop names, typeArrayOop times); 1.17 + ThreadTimesClosure(objArrayHandle names, typeArrayOop times); 1.18 + ~ThreadTimesClosure(); 1.19 virtual void do_thread(Thread* thread); 1.20 + void do_unlocked(); 1.21 int count() { return _count; } 1.22 }; 1.23 1.24 -ThreadTimesClosure::ThreadTimesClosure(objArrayOop names, 1.25 +ThreadTimesClosure::ThreadTimesClosure(objArrayHandle names, 1.26 typeArrayOop times) { 1.27 - assert(names != NULL, "names was NULL"); 1.28 + assert(names() != NULL, "names was NULL"); 1.29 assert(times != NULL, "times was NULL"); 1.30 - _names = names; 1.31 + _names_strings = names; 1.32 _names_len = names->length(); 1.33 + _names_chars = NEW_C_HEAP_ARRAY(char*, _names_len, mtInternal); 1.34 _times = times; 1.35 _times_len = times->length(); 1.36 _count = 0; 1.37 } 1.38 1.39 +// 1.40 +// Called with Threads_lock held 1.41 +// 1.42 void ThreadTimesClosure::do_thread(Thread* thread) { 1.43 - Handle s; 1.44 assert(thread != NULL, "thread was NULL"); 1.45 1.46 // exclude externally visible JavaThreads 1.47 @@ -1842,16 +1848,32 @@ 1.48 } 1.49 1.50 EXCEPTION_MARK; 1.51 + ResourceMark rm(THREAD); // thread->name() uses ResourceArea 1.52 1.53 assert(thread->name() != NULL, "All threads should have a name"); 1.54 - s = java_lang_String::create_from_str(thread->name(), CHECK); 1.55 - _names->obj_at_put(_count, s()); 1.56 - 1.57 + _names_chars[_count] = strdup(thread->name()); 1.58 _times->long_at_put(_count, os::is_thread_cpu_time_supported() ? 1.59 os::thread_cpu_time(thread) : -1); 1.60 _count++; 1.61 } 1.62 1.63 +// Called without Threads_lock, we can allocate String objects. 1.64 +void ThreadTimesClosure::do_unlocked() { 1.65 + 1.66 + EXCEPTION_MARK; 1.67 + for (int i = 0; i < _count; i++) { 1.68 + Handle s = java_lang_String::create_from_str(_names_chars[i], CHECK); 1.69 + _names_strings->obj_at_put(i, s()); 1.70 + } 1.71 +} 1.72 + 1.73 +ThreadTimesClosure::~ThreadTimesClosure() { 1.74 + for (int i = 0; i < _count; i++) { 1.75 + free(_names_chars[i]); 1.76 + } 1.77 + FREE_C_HEAP_ARRAY(char *, _names_chars, mtInternal); 1.78 +} 1.79 + 1.80 // Fills names with VM internal thread names and times with the corresponding 1.81 // CPU times. If names or times is NULL, a NullPointerException is thrown. 1.82 // If the element type of names is not String, an IllegalArgumentException is 1.83 @@ -1878,12 +1900,12 @@ 1.84 typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(times)); 1.85 typeArrayHandle times_ah(THREAD, ta); 1.86 1.87 - ThreadTimesClosure ttc(names_ah(), times_ah()); 1.88 + ThreadTimesClosure ttc(names_ah, times_ah()); 1.89 { 1.90 MutexLockerEx ml(Threads_lock); 1.91 Threads::threads_do(&ttc); 1.92 } 1.93 - 1.94 + ttc.do_unlocked(); 1.95 return ttc.count(); 1.96 JVM_END 1.97