< prev index next >

src/hotspot/share/prims/jvmtiEnvBase.cpp

Print this page

        

@@ -558,11 +558,11 @@
 vframe*
 JvmtiEnvBase::vframeFor(JavaThread* java_thread, jint depth) {
   if (!java_thread->has_last_Java_frame()) {
     return NULL;
   }
-  RegisterMap reg_map(java_thread);
+  RegisterMap reg_map(java_thread, true, true);
   vframe *vf = java_thread->last_java_vframe(&reg_map);
   int d = 0;
   while ((vf != NULL) && (d < depth)) {
     vf = vf->java_sender();
     d++;

@@ -621,11 +621,11 @@
     return ret;  // no Java frames so no monitors
   }
 
   ResourceMark rm;
   HandleMark   hm;
-  RegisterMap  reg_map(java_thread);
+  RegisterMap  reg_map(java_thread, true, true);
 
   for(javaVFrame *jvf=java_thread->last_java_vframe(&reg_map); jvf != NULL;
                                                  jvf = jvf->java_sender()) {
     GrowableArray<MonitorInfo*>* mons = jvf->monitors();
     if (!mons->is_empty()) {

@@ -694,11 +694,11 @@
          "at safepoint or target thread is suspended");
 
   if (java_thread->has_last_Java_frame()) {
     ResourceMark rm;
     HandleMark   hm;
-    RegisterMap  reg_map(java_thread);
+    RegisterMap  reg_map(java_thread, true, true);
 
     int depth = 0;
     for (javaVFrame *jvf = java_thread->last_java_vframe(&reg_map); jvf != NULL;
          jvf = jvf->java_sender()) {
       if (MaxJavaStackTraceDepth == 0 || depth++ < MaxJavaStackTraceDepth) {  // check for stack too deep

@@ -803,83 +803,99 @@
 
   return err;
 }
 
 jvmtiError
+JvmtiEnvBase::get_stack_trace(javaVFrame *jvf,
+                              jint start_depth, jint max_count,
+                              jvmtiFrameInfo* frame_buffer, jint* count_ptr) {
+  Thread* current_thread = Thread::current();
+  ResourceMark rm(current_thread);
+  HandleMark hm(current_thread);
+  int count = 0;
+
+  if (start_depth != 0) {
+    if (start_depth > 0) {
+      for (int j = 0; j < start_depth && jvf != NULL; j++) {
+        jvf = jvf->java_sender();
+      }
+      if (jvf == NULL) {
+        // start_depth is deeper than the stack depth
+        return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+      }
+    } else { // start_depth < 0
+      // we are referencing the starting depth based on the oldest
+      // part of the stack.
+      // optimize to limit the number of times that java_sender() is called
+      javaVFrame *jvf_cursor = jvf;
+      javaVFrame *jvf_prev = NULL;
+      javaVFrame *jvf_prev_prev = NULL;
+      int j = 0;
+      while (jvf_cursor != NULL) {
+        jvf_prev_prev = jvf_prev;
+        jvf_prev = jvf_cursor;
+        for (j = 0; j > start_depth && jvf_cursor != NULL; j--) {
+          jvf_cursor = jvf_cursor->java_sender();
+        }
+      }
+      if (j == start_depth) {
+        // previous pointer is exactly where we want to start
+        jvf = jvf_prev;
+      } else {
+        // we need to back up further to get to the right place
+        if (jvf_prev_prev == NULL) {
+          // the -start_depth is greater than the stack depth
+          return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+        }
+        // j now is the number of frames on the stack starting with
+        // jvf_prev, we start from jvf_prev_prev and move older on
+        // the stack that many, the result is -start_depth frames
+        // remaining.
+        jvf = jvf_prev_prev;
+        for (; j < 0; j++) {
+          jvf = jvf->java_sender();
+        }
+      }
+    }
+  }
+  for (; count < max_count && jvf != NULL; count++) {
+    frame_buffer[count].method = jvf->method()->jmethod_id();
+    frame_buffer[count].location = (jvf->method()->is_native() ? -1 : jvf->bci());
+    jvf = jvf->java_sender();
+  }
+  *count_ptr = count;
+  return JVMTI_ERROR_NONE;
+}
+
+jvmtiError
 JvmtiEnvBase::get_stack_trace(JavaThread *java_thread,
                               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");
   int count = 0;
+  jvmtiError err = JVMTI_ERROR_NONE;
+
   if (java_thread->has_last_Java_frame()) {
-    RegisterMap reg_map(java_thread);
+    RegisterMap reg_map(java_thread, true, true);
     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) {
-        for (int j = 0; j < start_depth && jvf != NULL; j++) {
-          jvf = jvf->java_sender();
-        }
-        if (jvf == NULL) {
-          // start_depth is deeper than the stack depth
-          return JVMTI_ERROR_ILLEGAL_ARGUMENT;
-        }
-      } else { // start_depth < 0
-        // we are referencing the starting depth based on the oldest
-        // part of the stack.
-        // optimize to limit the number of times that java_sender() is called
-        javaVFrame *jvf_cursor = jvf;
-        javaVFrame *jvf_prev = NULL;
-        javaVFrame *jvf_prev_prev = NULL;
-        int j = 0;
-        while (jvf_cursor != NULL) {
-          jvf_prev_prev = jvf_prev;
-          jvf_prev = jvf_cursor;
-          for (j = 0; j > start_depth && jvf_cursor != NULL; j--) {
-            jvf_cursor = jvf_cursor->java_sender();
-          }
-        }
-        if (j == start_depth) {
-          // previous pointer is exactly where we want to start
-          jvf = jvf_prev;
-        } else {
-          // we need to back up further to get to the right place
-          if (jvf_prev_prev == NULL) {
-            // the -start_depth is greater than the stack depth
-            return JVMTI_ERROR_ILLEGAL_ARGUMENT;
-          }
-          // j now is the number of frames on the stack starting with
-          // jvf_prev, we start from jvf_prev_prev and move older on
-          // the stack that many, the result is -start_depth frames
-          // remaining.
-          jvf = jvf_prev_prev;
-          for (; j < 0; j++) {
-            jvf = jvf->java_sender();
-          }
-        }
-      }
-    }
-    for (; count < max_count && jvf != NULL; count++) {
-      frame_buffer[count].method = jvf->method()->jmethod_id();
-      frame_buffer[count].location = (jvf->method()->is_native() ? -1 : jvf->bci());
-      jvf = jvf->java_sender();
-    }
+
+    err = get_stack_trace(jvf, start_depth, max_count, frame_buffer, count_ptr);
   } else {
+    *count_ptr = 0;
     if (start_depth != 0) {
       // no frames and there is a starting depth
-      return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+      err = JVMTI_ERROR_ILLEGAL_ARGUMENT;
     }
   }
-  *count_ptr = count;
-  return JVMTI_ERROR_NONE;
+  return err;
 }
 
 jvmtiError
 JvmtiEnvBase::get_frame_count(JvmtiThreadState *state, jint *count_ptr) {
   assert((state != NULL),

@@ -1593,5 +1609,90 @@
       && !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) {
     _result = ((JvmtiEnvBase*)_env)->get_frame_location(_java_thread, _depth,
                                                         _method_ptr, _location_ptr);
   }
 }
+
+void
+VM_GetFiberThread::doit() {
+  oop carrier_thread = java_lang_Fiber::carrier_thread(_fiber_h());
+  *_carrier_thread_ptr = (jthread)JNIHandles::make_local(_current_thread, carrier_thread);
+}
+
+static
+javaVFrame* get_fiber_jvf(Thread* cur_thread, oop fiber) {
+  oop cont = java_lang_Fiber::continuation(fiber);
+  javaVFrame* jvf = NULL;
+
+  if (cont != NULL && java_lang_Continuation::is_mounted(cont)) {
+    oop carrier_thread = java_lang_Fiber::carrier_thread(fiber);
+    JavaThread* java_thread = java_lang_Thread::thread(carrier_thread);
+    vframeStream vfs(java_thread, Handle(cur_thread, Continuation::continuation_scope(cont)));
+    
+    if (!vfs.at_end()) {
+      jvf = vfs.asJavaVFrame();
+    }
+  } else {
+    Handle cont_h(cur_thread, cont);
+    vframeStream vfs(cont_h);
+
+    if (!vfs.at_end()) {
+      jvf = vfs.asJavaVFrame();
+    }
+  }
+  return jvf;
+}
+
+void
+VM_GetFiberStackTrace::doit() {
+  Thread* cur_thread = Thread::current();
+  ResourceMark rm(cur_thread);
+  HandleMark hm(cur_thread);
+  javaVFrame *jvf = get_fiber_jvf(cur_thread, _fiber_h());
+  _result = ((JvmtiEnvBase *)_env)->get_stack_trace(jvf,
+                                                    _start_depth, _max_count,
+                                                    _frame_buffer, _count_ptr);
+}
+
+void
+VM_GetFiberFrameCount::doit() {
+  Thread* cur_thread = Thread::current();
+  ResourceMark rm(cur_thread);
+  HandleMark hm(cur_thread);
+  javaVFrame *jvf = get_fiber_jvf(cur_thread, _fiber_h());
+  int count = 0;
+
+  while (jvf != NULL) {
+    Method* method = jvf->method();
+    jvf = jvf->java_sender();
+    count++;
+  }
+  *_count_ptr = count;
+}
+
+void
+VM_GetFiberFrameLocation::doit() {
+  Thread* cur_thread = Thread::current();
+  ResourceMark rm(cur_thread);
+  HandleMark hm(cur_thread);
+  javaVFrame *jvf = get_fiber_jvf(cur_thread, _fiber_h());
+  int  depth = -1;
+
+  while (jvf != NULL && depth < _depth) {
+    Method* method = jvf->method();
+    jvf = jvf->java_sender();
+    depth++;
+  }
+
+  if (depth < _depth) {
+    _result = JVMTI_ERROR_NO_MORE_FRAMES;
+    return;
+  }
+
+  Method* method = jvf->method();
+  if (method->is_native()) {
+    *_location_ptr = -1;
+  } else {
+    *_location_ptr = jvf->bci();
+  }
+  *_method_ptr = method->jmethod_id();
+}
< prev index next >