< prev index next >

src/hotspot/share/services/threadService.cpp

Print this page




   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"

  26 #include "classfile/systemDictionary.hpp"
  27 #include "memory/allocation.hpp"
  28 #include "memory/heapInspection.hpp"
  29 #include "memory/oopFactory.hpp"
  30 #include "memory/resourceArea.hpp"
  31 #include "oops/instanceKlass.hpp"
  32 #include "oops/objArrayKlass.hpp"
  33 #include "oops/objArrayOop.inline.hpp"
  34 #include "oops/oop.inline.hpp"
  35 #include "runtime/atomic.hpp"
  36 #include "runtime/handles.inline.hpp"
  37 #include "runtime/init.hpp"
  38 #include "runtime/objectMonitor.inline.hpp"
  39 #include "runtime/thread.inline.hpp"
  40 #include "runtime/threadSMR.inline.hpp"
  41 #include "runtime/vframe.hpp"
  42 #include "runtime/vmThread.hpp"
  43 #include "runtime/vmOperations.hpp"
  44 #include "services/threadService.hpp"
  45 


 538   for (ThreadSnapshot* ts = _snapshots; ts != NULL; ts = ts->next()) {
 539     ts->oops_do(f);
 540   }
 541 }
 542 
 543 void ThreadDumpResult::metadata_do(void f(Metadata*)) {
 544   for (ThreadSnapshot* ts = _snapshots; ts != NULL; ts = ts->next()) {
 545     ts->metadata_do(f);
 546   }
 547 }
 548 
 549 ThreadsList* ThreadDumpResult::t_list() {
 550   return _setter.list();
 551 }
 552 
 553 StackFrameInfo::StackFrameInfo(javaVFrame* jvf, bool with_lock_info) {
 554   _method = jvf->method();
 555   _bci = jvf->bci();
 556   _class_holder = _method->method_holder()->klass_holder();
 557   _locked_monitors = NULL;

 558   if (with_lock_info) {
 559     ResourceMark rm;
 560     GrowableArray<MonitorInfo*>* list = jvf->locked_monitors();
 561     int length = list->length();
 562     if (length > 0) {
 563       _locked_monitors = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(length, true);
 564       for (int i = 0; i < length; i++) {
 565         MonitorInfo* monitor = list->at(i);
 566         assert(monitor->owner() != NULL, "This monitor must have an owning object");
 567         _locked_monitors->append(monitor->owner());
 568       }
 569     }
 570   }
 571 }
 572 
 573 void StackFrameInfo::oops_do(OopClosure* f) {
 574   if (_locked_monitors != NULL) {
 575     int length = _locked_monitors->length();
 576     for (int i = 0; i < length; i++) {
 577       f->do_oop((oop*) _locked_monitors->adr_at(i));
 578     }
 579   }
 580   f->do_oop(&_class_holder);

 581 }
 582 
 583 void StackFrameInfo::metadata_do(void f(Metadata*)) {
 584   f(_method);
 585 }
 586 
 587 void StackFrameInfo::print_on(outputStream* st) const {
 588   ResourceMark rm;
 589   java_lang_Throwable::print_stack_element(st, method(), bci());
 590   int len = (_locked_monitors != NULL ? _locked_monitors->length() : 0);
 591   for (int i = 0; i < len; i++) {
 592     oop o = _locked_monitors->at(i);
 593     st->print_cr("\t- locked <" INTPTR_FORMAT "> (a %s)", p2i(o), o->klass()->external_name());
 594   }
 595 
 596 }
 597 
 598 // Iterate through monitor cache to find JNI locked monitors
 599 class InflatedMonitorsClosure: public MonitorClosure {
 600 private:


 624     _jni_locked_monitors = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(INITIAL_ARRAY_SIZE, true);
 625   } else {
 626     _jni_locked_monitors = NULL;
 627   }
 628 }
 629 
 630 ThreadStackTrace::~ThreadStackTrace() {
 631   for (int i = 0; i < _frames->length(); i++) {
 632     delete _frames->at(i);
 633   }
 634   delete _frames;
 635   if (_jni_locked_monitors != NULL) {
 636     delete _jni_locked_monitors;
 637   }
 638 }
 639 
 640 void ThreadStackTrace::dump_stack_at_safepoint(int maxDepth) {
 641   assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped");
 642 
 643   if (_thread->has_last_Java_frame()) {
 644     RegisterMap reg_map(_thread);
 645     vframe* start_vf = _thread->last_java_vframe(&reg_map);
 646     int count = 0;
 647     for (vframe* f = start_vf; f; f = f->sender() ) {
 648       if (maxDepth >= 0 && count == maxDepth) {
 649         // Skip frames if more than maxDepth
 650         break;
 651       }
 652       if (f->is_java_frame()) {
 653         javaVFrame* jvf = javaVFrame::cast(f);
 654         add_stack_frame(jvf);
 655         count++;
 656       } else {
 657         // Ignore non-Java frames
 658       }
 659     }
 660   }
 661 
 662   if (_with_locked_monitors) {
 663     // Iterate inflated monitors and find monitors locked by this thread
 664     // not found in the stack


 682       assert(monitor != NULL, "must be a Java object");
 683       if (oopDesc::equals(monitor, object)) {
 684         found = true;
 685         break;
 686       }
 687     }
 688   }
 689   return found;
 690 }
 691 
 692 Handle ThreadStackTrace::allocate_fill_stack_trace_element_array(TRAPS) {
 693   InstanceKlass* ik = SystemDictionary::StackTraceElement_klass();
 694   assert(ik != NULL, "must be loaded in 1.4+");
 695 
 696   // Allocate an array of java/lang/StackTraceElement object
 697   objArrayOop ste = oopFactory::new_objArray(ik, _depth, CHECK_NH);
 698   objArrayHandle backtrace(THREAD, ste);
 699   for (int j = 0; j < _depth; j++) {
 700     StackFrameInfo* frame = _frames->at(j);
 701     methodHandle mh(THREAD, frame->method());
 702     oop element = java_lang_StackTraceElement::create(mh, frame->bci(), CHECK_NH);

 703     backtrace->obj_at_put(j, element);
 704   }
 705   return backtrace;
 706 }
 707 
 708 void ThreadStackTrace::add_stack_frame(javaVFrame* jvf) {
 709   StackFrameInfo* frame = new StackFrameInfo(jvf, _with_locked_monitors);
 710   _frames->append(frame);
 711   _depth++;
 712 }
 713 
 714 void ThreadStackTrace::oops_do(OopClosure* f) {
 715   int length = _frames->length();
 716   for (int i = 0; i < length; i++) {
 717     _frames->at(i)->oops_do(f);
 718   }
 719 
 720   length = (_jni_locked_monitors != NULL ? _jni_locked_monitors->length() : 0);
 721   for (int j = 0; j < length; j++) {
 722     f->do_oop((oop*) _jni_locked_monitors->adr_at(j));




   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/javaClasses.inline.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "memory/allocation.hpp"
  29 #include "memory/heapInspection.hpp"
  30 #include "memory/oopFactory.hpp"
  31 #include "memory/resourceArea.hpp"
  32 #include "oops/instanceKlass.hpp"
  33 #include "oops/objArrayKlass.hpp"
  34 #include "oops/objArrayOop.inline.hpp"
  35 #include "oops/oop.inline.hpp"
  36 #include "runtime/atomic.hpp"
  37 #include "runtime/handles.inline.hpp"
  38 #include "runtime/init.hpp"
  39 #include "runtime/objectMonitor.inline.hpp"
  40 #include "runtime/thread.inline.hpp"
  41 #include "runtime/threadSMR.inline.hpp"
  42 #include "runtime/vframe.hpp"
  43 #include "runtime/vmThread.hpp"
  44 #include "runtime/vmOperations.hpp"
  45 #include "services/threadService.hpp"
  46 


 539   for (ThreadSnapshot* ts = _snapshots; ts != NULL; ts = ts->next()) {
 540     ts->oops_do(f);
 541   }
 542 }
 543 
 544 void ThreadDumpResult::metadata_do(void f(Metadata*)) {
 545   for (ThreadSnapshot* ts = _snapshots; ts != NULL; ts = ts->next()) {
 546     ts->metadata_do(f);
 547   }
 548 }
 549 
 550 ThreadsList* ThreadDumpResult::t_list() {
 551   return _setter.list();
 552 }
 553 
 554 StackFrameInfo::StackFrameInfo(javaVFrame* jvf, bool with_lock_info) {
 555   _method = jvf->method();
 556   _bci = jvf->bci();
 557   _class_holder = _method->method_holder()->klass_holder();
 558   _locked_monitors = NULL;
 559   _cont_scope_name = (jvf->continuation() != NULL) ? java_lang_ContinuationScope::name(java_lang_Continuation::scope(jvf->continuation())) : (oop)NULL;
 560   if (with_lock_info) {
 561     ResourceMark rm;
 562     GrowableArray<MonitorInfo*>* list = jvf->locked_monitors();
 563     int length = list->length();
 564     if (length > 0) {
 565       _locked_monitors = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(length, true);
 566       for (int i = 0; i < length; i++) {
 567         MonitorInfo* monitor = list->at(i);
 568         assert(monitor->owner() != NULL, "This monitor must have an owning object");
 569         _locked_monitors->append(monitor->owner());
 570       }
 571     }
 572   }
 573 }
 574 
 575 void StackFrameInfo::oops_do(OopClosure* f) {
 576   if (_locked_monitors != NULL) {
 577     int length = _locked_monitors->length();
 578     for (int i = 0; i < length; i++) {
 579       f->do_oop((oop*) _locked_monitors->adr_at(i));
 580     }
 581   }
 582   f->do_oop(&_class_holder);
 583   f->do_oop(&_cont_scope_name);
 584 }
 585 
 586 void StackFrameInfo::metadata_do(void f(Metadata*)) {
 587   f(_method);
 588 }
 589 
 590 void StackFrameInfo::print_on(outputStream* st) const {
 591   ResourceMark rm;
 592   java_lang_Throwable::print_stack_element(st, method(), bci());
 593   int len = (_locked_monitors != NULL ? _locked_monitors->length() : 0);
 594   for (int i = 0; i < len; i++) {
 595     oop o = _locked_monitors->at(i);
 596     st->print_cr("\t- locked <" INTPTR_FORMAT "> (a %s)", p2i(o), o->klass()->external_name());
 597   }
 598 
 599 }
 600 
 601 // Iterate through monitor cache to find JNI locked monitors
 602 class InflatedMonitorsClosure: public MonitorClosure {
 603 private:


 627     _jni_locked_monitors = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(INITIAL_ARRAY_SIZE, true);
 628   } else {
 629     _jni_locked_monitors = NULL;
 630   }
 631 }
 632 
 633 ThreadStackTrace::~ThreadStackTrace() {
 634   for (int i = 0; i < _frames->length(); i++) {
 635     delete _frames->at(i);
 636   }
 637   delete _frames;
 638   if (_jni_locked_monitors != NULL) {
 639     delete _jni_locked_monitors;
 640   }
 641 }
 642 
 643 void ThreadStackTrace::dump_stack_at_safepoint(int maxDepth) {
 644   assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped");
 645 
 646   if (_thread->has_last_Java_frame()) {
 647     RegisterMap reg_map(_thread, true, false);
 648     vframe* start_vf = _thread->last_java_vframe(&reg_map);
 649     int count = 0;
 650     for (vframe* f = start_vf; f; f = f->sender() ) {
 651       if (maxDepth >= 0 && count == maxDepth) {
 652         // Skip frames if more than maxDepth
 653         break;
 654       }
 655       if (f->is_java_frame()) {
 656         javaVFrame* jvf = javaVFrame::cast(f);
 657         add_stack_frame(jvf);
 658         count++;
 659       } else {
 660         // Ignore non-Java frames
 661       }
 662     }
 663   }
 664 
 665   if (_with_locked_monitors) {
 666     // Iterate inflated monitors and find monitors locked by this thread
 667     // not found in the stack


 685       assert(monitor != NULL, "must be a Java object");
 686       if (oopDesc::equals(monitor, object)) {
 687         found = true;
 688         break;
 689       }
 690     }
 691   }
 692   return found;
 693 }
 694 
 695 Handle ThreadStackTrace::allocate_fill_stack_trace_element_array(TRAPS) {
 696   InstanceKlass* ik = SystemDictionary::StackTraceElement_klass();
 697   assert(ik != NULL, "must be loaded in 1.4+");
 698 
 699   // Allocate an array of java/lang/StackTraceElement object
 700   objArrayOop ste = oopFactory::new_objArray(ik, _depth, CHECK_NH);
 701   objArrayHandle backtrace(THREAD, ste);
 702   for (int j = 0; j < _depth; j++) {
 703     StackFrameInfo* frame = _frames->at(j);
 704     methodHandle mh(THREAD, frame->method());
 705     Handle contScopeNameH(THREAD, frame->cont_scope_name());
 706     oop element = java_lang_StackTraceElement::create(mh, frame->bci(), contScopeNameH, CHECK_NH);
 707     backtrace->obj_at_put(j, element);
 708   }
 709   return backtrace;
 710 }
 711 
 712 void ThreadStackTrace::add_stack_frame(javaVFrame* jvf) {
 713   StackFrameInfo* frame = new StackFrameInfo(jvf, _with_locked_monitors);
 714   _frames->append(frame);
 715   _depth++;
 716 }
 717 
 718 void ThreadStackTrace::oops_do(OopClosure* f) {
 719   int length = _frames->length();
 720   for (int i = 0; i < length; i++) {
 721     _frames->at(i)->oops_do(f);
 722   }
 723 
 724   length = (_jni_locked_monitors != NULL ? _jni_locked_monitors->length() : 0);
 725   for (int j = 0; j < length; j++) {
 726     f->do_oop((oop*) _jni_locked_monitors->adr_at(j));


< prev index next >