< prev index next >

src/hotspot/share/prims/jvmtiEnvBase.hpp

Print this page
@@ -80,10 +80,15 @@
  
    static void entering_dying_thread_env_iteration() { ++_dying_thread_env_iteration_count; }
    static void leaving_dying_thread_env_iteration()  { --_dying_thread_env_iteration_count; }
    static bool is_inside_dying_thread_env_iteration(){ return _dying_thread_env_iteration_count > 0; }
  
+   static jvmtiError suspend_thread(oop thread_oop, JavaThread* java_thread, bool single_suspend,
+                                    int* need_safepoint_p);
+   static jvmtiError resume_thread(oop thread_oop, JavaThread* java_thread, bool single_suspend);
+   static jvmtiError check_thread_list(jint count, const jthread* list);
+   static bool is_in_thread_list(jint count, const jthread* list, oop jt_oop);
   private:
  
    enum {
        JVMTI_MAGIC    = 0x71EE,
        DISPOSED_MAGIC = 0xDEFC,

@@ -151,10 +156,37 @@
  
    static ByteSize jvmti_external_offset() {
      return byte_offset_of(JvmtiEnvBase, _jvmti_external);
    };
  
+   static jvmtiError get_JavaThread(ThreadsList* tlist, jthread thread, JavaThread** jt_pp) {
+     jvmtiError err = JVMTI_ERROR_NONE;
+     if (thread == NULL) {
+       *jt_pp = JavaThread::current();
+     } else {
+       err = JvmtiExport::cv_external_thread_to_JavaThread(tlist, thread, jt_pp, NULL);
+     }
+     return err;
+   }
+ 
+   // If there is a virtual thread mounted to the JavaThread* then
+   // return virtual thread oop. Otherwise, return thread oop.
+   static oop get_vthread_or_thread_oop(JavaThread* jt) {
+     oop result = jt->threadObj();
+     if (jt->mounted_vthread() != NULL) {
+       result = jt->mounted_vthread();
+     }
+     return result;
+   }
+ 
+   static jvmtiError get_threadOop_and_JavaThread(ThreadsList* t_list, jthread thread,
+                                                  JavaThread** jt_pp, oop* thread_oop_p);
+ 
+   // Return true if java thread is a carrier thread with a mounted virtual thread.
+   static bool cthread_with_mounted_vthread(JavaThread* jt);
+   static bool cthread_with_continuation(JavaThread* jt);
+ 
    static JvmtiEnv* JvmtiEnv_from_jvmti_env(jvmtiEnv *env) {
      return (JvmtiEnv*)((intptr_t)env - in_bytes(jvmti_external_offset()));
    };
  
    jvmtiCapabilities *get_capabilities()             { return &_current_capabilities; }

@@ -284,29 +316,64 @@
                                     JavaThread* java_thread,
                                     javaVFrame *jvf,
                                     GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list,
                                     jint depth);
   public:
-   static vframe* vframeForNoProcess(JavaThread* java_thread, jint depth);
+   static vframe* vframeForNoProcess(JavaThread* java_thread, jint depth, bool for_cont = false);
  
    // get a field descriptor for the specified class and field
    static bool get_field_descriptor(Klass* k, jfieldID field, fieldDescriptor* fd);
  
+   // check and skip frames hidden in mount/unmount transitions
+   static javaVFrame* check_and_skip_hidden_frames(bool is_in_VTMT, javaVFrame* jvf);
+   static javaVFrame* check_and_skip_hidden_frames(JavaThread* jt, javaVFrame* jvf);
+   static javaVFrame* check_and_skip_hidden_frames(oop vthread, javaVFrame* jvf);
+ 
+   // check if virtual thread is not terminated (alive)
+   static bool is_vthread_alive(oop vt);
+ 
+   // get virtual thread last java vframe
+   static javaVFrame* get_vthread_jvf(oop vthread);
+ 
+   // get carrier thread last java vframe
+   static javaVFrame* get_last_java_vframe(JavaThread* jt, RegisterMap* reg_map);
+ 
+   // get ordinary thread thread state
+   static jint get_thread_state(oop thread_oop, JavaThread* jt);
+ 
+   // get virtual thread thread state
+   static jint get_vthread_state(oop thread_oop);
+ 
+   // enumerates the live threads in the given thread group
+   static int get_live_threads(JavaThread* current_thread, Handle group_hdl, Handle **thread_objs_p);
+ 
+   // enumerates the subgroups in the given thread group
+   static int get_subgroups(JavaThread* current_thread, Handle group_hdl, Handle **group_objs_p);
+ 
    // JVMTI API helper functions which are called when target thread is suspended
    // or at safepoint / thread local handshake.
-   jvmtiError get_frame_count(JvmtiThreadState *state, jint *count_ptr);
+   static jint get_frame_count(javaVFrame* jvf);
+   jvmtiError get_frame_count(JavaThread* java_thread, jint *count_ptr);
+   jvmtiError get_frame_count(oop frame_oop, jint *count_ptr);
    jvmtiError get_frame_location(JavaThread* java_thread, jint depth,
-                                               jmethodID* method_ptr, jlocation* location_ptr);
+                                 jmethodID* method_ptr, jlocation* location_ptr);
+   jvmtiError get_frame_location(oop vthread_oop, jint depth,
+                                 jmethodID* method_ptr, jlocation* location_ptr);
    jvmtiError get_object_monitor_usage(JavaThread *calling_thread,
                                                      jobject object, jvmtiMonitorUsage* info_ptr);
+   jvmtiError get_stack_trace(javaVFrame *jvf,
+                              jint stack_depth, jint max_count,
+                              jvmtiFrameInfo* frame_buffer, jint* count_ptr);
    jvmtiError get_stack_trace(JavaThread *java_thread,
                                             jint stack_depth, jint max_count,
                                             jvmtiFrameInfo* frame_buffer, jint* count_ptr);
-   jvmtiError get_current_contended_monitor(JavaThread *calling_thread, JavaThread *java_thread,
+   jvmtiError get_current_contended_monitor(JavaThread* calling_thread, JavaThread *java_thread,
                                             jobject *monitor_ptr);
-   jvmtiError get_owned_monitors(JavaThread *calling_thread, JavaThread* java_thread,
+   jvmtiError get_owned_monitors(JavaThread* calling_thread, JavaThread* java_thread,
                                  GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list);
+   jvmtiError get_owned_monitors(JavaThread *calling_thread, JavaThread* java_thread, javaVFrame* jvf,
+                           GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list);
    static jvmtiError check_top_frame(Thread* current_thread, JavaThread* java_thread,
                                      jvalue value, TosState tos, Handle* ret_ob_h);
    jvmtiError force_early_return(JavaThread* java_thread, jvalue value, TosState tos);
  };
  

@@ -411,11 +478,10 @@
        _env(env),
        _owned_monitors_list(owned_monitor_list) {}
    void do_thread(Thread *target);
  };
  
- 
  // VM operation to get object monitor usage.
  class VM_GetObjectMonitorUsage : public VM_Operation {
  private:
    JvmtiEnv *_env;
    jobject _object;

@@ -473,16 +539,29 @@
        _frame_buffer(frame_buffer),
        _count_ptr(count_ptr) {}
    void do_thread(Thread *target);
  };
  
+ #ifdef ASSERT
+ // HandshakeClosure to print stack trace in JvmtiVTMTDisabler error handling
+ class PrintStackTraceClosure : public HandshakeClosure {
+  public:
+   static void do_thread_impl(Thread *target);
+ 
+   PrintStackTraceClosure()
+       : HandshakeClosure("PrintStackTraceClosure") {}
+   void do_thread(Thread *target);
+ };
+ #endif
+ 
  // forward declaration
  struct StackInfoNode;
  
  // Get stack trace at safepoint or at direct handshake.
  class MultipleStackTracesCollector {
  private:
+   friend class VM_GetThreadListStackTraces;
    JvmtiEnv *_env;
    jint _max_frame_count;
    jvmtiStackInfo *_stack_info;
    jvmtiError _result;
    int _frame_count_total;

@@ -536,10 +615,12 @@
  private:
    jint _thread_count;
    const jthread* _thread_list;
    MultipleStackTracesCollector _collector;
  
+   JvmtiEnvBase *env() { return _collector.env(); }
+ 
  public:
    VM_GetThreadListStackTraces(JvmtiEnv *env, jint thread_count, const jthread* thread_list, jint max_frame_count)
        : _thread_count(thread_count),
          _thread_list(thread_list),
          _collector(env, max_frame_count) {

@@ -548,10 +629,56 @@
    void doit();
    jvmtiStackInfo *stack_info()    { return _collector.stack_info(); }
    jvmtiError result()             { return _collector.result(); }
  };
  
+ class VM_VThreadGetStackTrace : public VM_Operation {
+ private:
+   JvmtiEnv *_env;
+   Handle _vthread_h;
+   jint _start_depth;
+   jint _max_count;
+   jvmtiFrameInfo* _frame_buffer;
+   jint* _count_ptr;
+   jvmtiError _result;
+ 
+ public:
+   VM_VThreadGetStackTrace(JvmtiEnv *env, Handle vthread_h,
+                           jint start_depth, jint max_count,
+                           jvmtiFrameInfo* frame_buffer, jint* count_ptr)
+     : _vthread_h(vthread_h),
+       _start_depth(start_depth),
+       _max_count(max_count),
+       _frame_buffer(frame_buffer),
+       _count_ptr(count_ptr),
+       _result(JVMTI_ERROR_NONE)
+   {}
+ 
+   VMOp_Type type() const { return VMOp_VThreadGetStackTrace; }
+   void doit();
+   jvmtiError result() { return _result; }
+ };
+ 
+ class VM_VThreadGetFrameCount : public VM_Operation {
+ private:
+   JvmtiEnv *_env;
+   Handle _vthread_h;
+   jint* _count_ptr;
+   jvmtiError _result;
+ 
+ public:
+   VM_VThreadGetFrameCount(JvmtiEnv *env, Handle vthread_h, jint* count_ptr)
+     : _vthread_h(vthread_h),
+       _count_ptr(count_ptr),
+       _result(JVMTI_ERROR_NONE)
+   {}
+ 
+   VMOp_Type type() const { return VMOp_VThreadGetFrameCount; }
+   void doit();
+   jvmtiError result() { return _result; }
+ };
+ 
  // HandshakeClosure to get single stack trace.
  class GetSingleStackTraceClosure : public HandshakeClosure {
  private:
    JavaThread *_calling_thread;
    jthread _jthread;

@@ -572,18 +699,16 @@
  
  // HandshakeClosure to count stack frames.
  class GetFrameCountClosure : public JvmtiHandshakeClosure {
  private:
    JvmtiEnv *_env;
-   JvmtiThreadState *_state;
    jint *_count_ptr;
  
  public:
-   GetFrameCountClosure(JvmtiEnv *env, JvmtiThreadState *state, jint *count_ptr)
+   GetFrameCountClosure(JvmtiEnv *env, jint *count_ptr)
      : JvmtiHandshakeClosure("GetFrameCount"),
        _env(env),
-       _state(state),
        _count_ptr(count_ptr) {}
    void do_thread(Thread *target);
  };
  
  // HandshakeClosure to get frame location.

@@ -603,10 +728,157 @@
        _method_ptr(method_ptr),
        _location_ptr(location_ptr) {}
    void do_thread(Thread *target);
  };
  
+ // HandshakeClosure to get virtual thread monitor information with stack depth.
+ class VThreadGetOwnedMonitorInfoClosure : public HandshakeClosure {
+ private:
+   JvmtiEnv *_env;
+   Handle _vthread_h;
+   GrowableArray<jvmtiMonitorStackDepthInfo*> *_owned_monitors_list;
+   jvmtiError _result;
+ 
+ public:
+   VThreadGetOwnedMonitorInfoClosure(JvmtiEnv* env,
+                             Handle vthread_h,
+                             GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list)
+     : HandshakeClosure("VThreadGetOwnedMonitorInfo"),
+       _env(env),
+       _vthread_h(vthread_h),
+       _owned_monitors_list(owned_monitors_list),
+       _result(JVMTI_ERROR_THREAD_NOT_ALIVE) {}
+ 
+   void do_thread(Thread *target);
+   jvmtiError result() { return _result; }
+ };
+ 
+ // HandshakeClosure to get virtual thread current contended monitor.
+ class VThreadGetCurrentContendedMonitorClosure : public HandshakeClosure {
+ private:
+   JvmtiEnv *_env;
+   Handle _vthread_h;
+   jobject *_owned_monitor_ptr;
+   jvmtiError _result;
+ 
+ public:
+   VThreadGetCurrentContendedMonitorClosure(JvmtiEnv *env, Handle vthread_h, jobject *mon_ptr)
+     : HandshakeClosure("VThreadGetCurrentContendedMonitor"),
+       _env(env),
+       _vthread_h(vthread_h),
+       _owned_monitor_ptr(mon_ptr),
+       _result(JVMTI_ERROR_THREAD_NOT_ALIVE) {}
+   jvmtiError result() { return _result; }
+   void do_thread(Thread *target);
+ };
+ 
+ // HandshakeClosure to get virtual thread thread at safepoint.
+ class VThreadGetThreadClosure : public HandshakeClosure {
+ private:
+   Handle _vthread_h;
+   jthread* _carrier_thread_ptr;
+   jvmtiError _result;
+ 
+ public:
+   VThreadGetThreadClosure(Handle vthread_h, jthread* carrier_thread_ptr)
+     : HandshakeClosure("VThreadGetThread"),
+       _vthread_h(vthread_h),
+       _carrier_thread_ptr(carrier_thread_ptr),
+       _result(JVMTI_ERROR_NONE) {}
+ 
+   void do_thread(Thread *target);
+   jvmtiError result() { return _result; }
+ };
+ 
+ // HandshakeClosure to get virtual thread stack trace at safepoint.
+ class VThreadGetStackTraceClosure : public HandshakeClosure {
+ private:
+   JvmtiEnv *_env;
+   Handle _vthread_h;
+   jint _start_depth;
+   jint _max_count;
+   jvmtiFrameInfo *_frame_buffer;
+   jint *_count_ptr;
+   jvmtiError _result;
+ 
+ public:
+   VThreadGetStackTraceClosure(JvmtiEnv *env, Handle vthread_h,
+                               jint start_depth, jint max_count,
+                               jvmtiFrameInfo* frame_buffer, jint* count_ptr)
+     : HandshakeClosure("VThreadGetStackTrace"),
+       _env(env),
+       _vthread_h(vthread_h),
+        _start_depth(start_depth),
+       _max_count(max_count),
+       _frame_buffer(frame_buffer),
+       _count_ptr(count_ptr),
+       _result(JVMTI_ERROR_NONE) {}
+ 
+   void do_thread(Thread *target);
+   jvmtiError result() { return _result; }
+ };
+ 
+ // HandshakeClosure to count virtual thread stack frames at safepoint.
+ class VThreadGetFrameCountClosure : public HandshakeClosure {
+ private:
+   JvmtiEnv *_env;
+   Handle _vthread_h;
+   jint *_count_ptr;
+   jvmtiError _result;
+ 
+ public:
+   VThreadGetFrameCountClosure(JvmtiEnv *env, Handle vthread_h, jint *count_ptr)
+     : HandshakeClosure("VThreadGetFrameCount"),
+       _env(env), _vthread_h(vthread_h), _count_ptr(count_ptr),
+       _result(JVMTI_ERROR_NONE) {}
+ 
+   void do_thread(Thread *target);
+   jvmtiError result() { return _result; }
+ };
+ 
+ // HandshakeClosure get to virtual thread frame location at safepoint.
+ class VThreadGetFrameLocationClosure : public HandshakeClosure {
+ private:
+   JvmtiEnv *_env;
+   Handle _vthread_h;
+   jint _depth;
+   jmethodID* _method_ptr;
+   jlocation* _location_ptr;
+   jvmtiError _result;
+ 
+ public:
+   VThreadGetFrameLocationClosure(JvmtiEnv *env, Handle vthread_h, jint depth,
+                                  jmethodID* method_ptr, jlocation* location_ptr)
+     : HandshakeClosure("VThreadGetFrameLocation"),
+       _env(env),
+       _vthread_h(vthread_h),
+       _depth(depth),
+       _method_ptr(method_ptr),
+       _location_ptr(location_ptr),
+       _result(JVMTI_ERROR_NONE) {}
+ 
+   void do_thread(Thread *target);
+   jvmtiError result() { return _result; }
+ };
+ 
+ // HandshakeClosure to get virtual thread state at safepoint.
+ class VThreadGetThreadStateClosure : public HandshakeClosure {
+ private:
+   Handle _vthread_h;
+   jint *_state_ptr;
+   jvmtiError _result;
+ 
+ public:
+   VThreadGetThreadStateClosure(Handle vthread_h, jint *state_ptr)
+     : HandshakeClosure("VThreadGetThreadState"),
+       _vthread_h(vthread_h),
+       _state_ptr(state_ptr),
+       _result(JVMTI_ERROR_NONE) {}
+ 
+   void do_thread(Thread *target);
+   jvmtiError result() { return _result; }
+ };
  
  // ResourceTracker
  //
  // ResourceTracker works a little like a ResourceMark. All allocates
  // using the resource tracker are recorded. If an allocate using the
< prev index next >