< prev index next >

src/hotspot/share/prims/jvmtiEnvBase.cpp

Print this page

        

@@ -814,17 +814,18 @@
                               jint start_depth, jint max_count,
                               jvmtiFrameInfo* frame_buffer, jint* count_ptr) {
 #ifdef ASSERT
   uint32_t debug_bits = 0;
 #endif
-  assert((SafepointSynchronize::is_at_safepoint() ||
-          java_thread->is_thread_fully_suspended(false, &debug_bits)),
-         "at safepoint or target thread is suspended");
+  Thread *current_thread = Thread::current();
+  assert(current_thread == java_thread ||
+         SafepointSynchronize::is_at_safepoint() ||
+         current_thread == java_thread->active_handshaker(),
+         "call by myself / at safepoint / at handshake");
   int count = 0;
   if (java_thread->has_last_Java_frame()) {
     RegisterMap reg_map(java_thread);
-    Thread* current_thread = Thread::current();
     ResourceMark rm(current_thread);
     javaVFrame *jvf = java_thread->last_java_vframe(&reg_map);
     HandleMark hm(current_thread);
     if (start_depth != 0) {
       if (start_depth > 0) {

@@ -1152,12 +1153,16 @@
 // buffer for the frame information, both allocated as resource objects.
 // Fill in both the jvmtiStackInfo and the jvmtiFrameInfo.
 // Note that either or both of thr and thread_oop
 // may be null if the thread is new or has exited.
 void
-VM_GetMultipleStackTraces::fill_frames(jthread jt, JavaThread *thr, oop thread_oop) {
-  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
+MultipleStackTracesCollector::fill_frames(jthread jt, JavaThread *thr, oop thread_oop) {
+  Thread *current_thread = Thread::current();
+  assert(current_thread == thr ||
+         SafepointSynchronize::is_at_safepoint() ||
+         current_thread == thr->active_handshaker(),
+         "call by myself / at safepoint / at handshake");
 
   jint state = 0;
   struct StackInfoNode *node = NEW_RESOURCE_OBJ(struct StackInfoNode);
   jvmtiStackInfo *infop = &(node->info);
   node->next = head();

@@ -1197,11 +1202,11 @@
 }
 
 // Based on the stack information in the linked list, allocate memory
 // block to return and fill it from the info in the linked list.
 void
-VM_GetMultipleStackTraces::allocate_and_fill_stacks(jint thread_count) {
+MultipleStackTracesCollector::allocate_and_fill_stacks(jint thread_count) {
   // do I need to worry about alignment issues?
   jlong alloc_size =  thread_count       * sizeof(jvmtiStackInfo)
                     + _frame_count_total * sizeof(jvmtiFrameInfo);
   env()->allocate(alloc_size, (unsigned char **)&_stack_info);
 

@@ -1246,18 +1251,32 @@
     if (err != JVMTI_ERROR_NONE) {
       // We got an error code so we don't have a JavaThread *, but
       // only return an error from here if we didn't get a valid
       // thread_oop.
       if (thread_oop == NULL) {
-        set_result(err);
+        _collector.set_result(err);
         return;
       }
       // We have a valid thread_oop.
     }
-    fill_frames(jt, java_thread, thread_oop);
+    _collector.fill_frames(jt, java_thread, thread_oop);
+  }
+  _collector.allocate_and_fill_stacks(_thread_count);
+}
+
+void
+GetSingleStackTraceClosure::do_thread(Thread *target) {
+  assert(target->is_Java_thread(), "just checking");
+  JavaThread *jt = (JavaThread *)target;
+  oop thread_oop = jt->threadObj();
+
+  if (!jt->is_exiting() && (thread_oop != NULL)) {
+    ResourceMark rm;
+    _collector.fill_frames((jthread)JNIHandles::make_local(_calling_thread, thread_oop),
+                           jt, thread_oop);
+    _collector.allocate_and_fill_stacks(1);
   }
-  allocate_and_fill_stacks(_thread_count);
 }
 
 void
 VM_GetAllStackTraces::doit() {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");

@@ -1270,15 +1289,15 @@
         !jt->is_exiting() &&
         java_lang_Thread::is_alive(thread_oop) &&
         !jt->is_hidden_from_external_view()) {
       ++_final_thread_count;
       // Handle block of the calling thread is used to create local refs.
-      fill_frames((jthread)JNIHandles::make_local(_calling_thread, thread_oop),
+      _collector.fill_frames((jthread)JNIHandles::make_local(_calling_thread, thread_oop),
                   jt, thread_oop);
     }
   }
-  allocate_and_fill_stacks(_final_thread_count);
+  _collector.allocate_and_fill_stacks(_final_thread_count);
 }
 
 // Verifies that the top frame is a java frame in an expected state.
 // Deoptimizes frame if needed.
 // Checks that the frame method signature matches the return type (tos).

@@ -1526,16 +1545,15 @@
                                                                     _owned_monitor_ptr);
   }
 }
 
 void
-VM_GetStackTrace::doit() {
-  _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
-  ThreadsListHandle tlh;
-  if (_java_thread != NULL && tlh.includes(_java_thread)
-      && !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) {
-    _result = ((JvmtiEnvBase *)_env)->get_stack_trace(_java_thread,
+GetStackTraceClosure::do_thread(Thread *target) {
+  assert(target->is_Java_thread(), "just checking");
+  JavaThread *jt = (JavaThread *)target;
+  if (!jt->is_exiting() && (jt->threadObj() != NULL)) {
+    _result = ((JvmtiEnvBase *)_env)->get_stack_trace(jt,
                                                       _start_depth, _max_count,
                                                       _frame_buffer, _count_ptr);
   }
 }
 
< prev index next >