< prev index next >

src/hotspot/share/classfile/javaClasses.cpp

Print this page
*** 1902,82 ***
  
  oop java_lang_Thread::park_blocker(oop java_thread) {
    return java_thread->obj_field_access<MO_RELAXED>(_park_blocker_offset);
  }
  
! // Obtain stack trace for platform or mounted virtual thread.
- // If jthread is a virtual thread and it has been unmounted (or remounted to different carrier) the method returns null.
- // The caller (java.lang.VirtualThread) handles returned nulls via retry.
  oop java_lang_Thread::async_get_stack_trace(jobject jthread, TRAPS) {
    ThreadsListHandle tlh(THREAD);
    JavaThread* java_thread = nullptr;
    oop thread_oop;
  
    bool has_java_thread = tlh.cv_internal_thread_to_JavaThread(jthread, &java_thread, &thread_oop);
!   if (!has_java_thread) {
      return nullptr;
    }
  
    class GetStackTraceHandshakeClosure : public HandshakeClosure {
    public:
      const Handle _thread_h;
      int _depth;
-     bool _retry_handshake;
      GrowableArray<Method*>* _methods;
      GrowableArray<int>*     _bcis;
  
      GetStackTraceHandshakeClosure(Handle thread_h) :
!         HandshakeClosure("GetStackTraceHandshakeClosure"), _thread_h(thread_h), _depth(0), _retry_handshake(false),
          _methods(nullptr), _bcis(nullptr) {
      }
      ~GetStackTraceHandshakeClosure() {
        delete _methods;
        delete _bcis;
      }
  
-     bool read_reset_retry() {
-       bool ret = _retry_handshake;
-       // If we re-execute the handshake this method need to return false
-       // when the handshake cannot be performed. (E.g. thread terminating)
-       _retry_handshake = false;
-       return ret;
-     }
- 
      void do_thread(Thread* th) {
!       if (!Thread::current()->is_Java_thread()) {
!         _retry_handshake = true;
          return;
        }
  
!       JavaThread* java_thread = JavaThread::cast(th);
! 
-       if (!java_thread->has_last_Java_frame()) {
-         return;
-       }
- 
-       bool carrier = false;
-       if (java_lang_VirtualThread::is_instance(_thread_h())) {
-         // Ensure _thread_h is still mounted to java_thread.
-         const ContinuationEntry* ce = java_thread->vthread_continuation();
-         if (ce == nullptr || ce->cont_oop(java_thread) != java_lang_VirtualThread::continuation(_thread_h())) {
-           // Target thread has been unmounted.
-           return;
-         }
-       } else {
-         carrier = (java_thread->vthread_continuation() != nullptr);
-       }
  
        const int max_depth = MaxJavaStackTraceDepth;
        const bool skip_hidden = !ShowHiddenFrames;
  
        // Pick minimum length that will cover most cases
        int init_length = 64;
        _methods = new (mtInternal) GrowableArray<Method*>(init_length, mtInternal);
        _bcis = new (mtInternal) GrowableArray<int>(init_length, mtInternal);
  
        int total_count = 0;
!       for (vframeStream vfst(java_thread, false, false, carrier); // we don't process frames as we don't care about oops
             !vfst.at_end() && (max_depth == 0 || max_depth != total_count);
             vfst.next()) {
  
          if (skip_hidden && (vfst.method()->is_hidden() ||
                              vfst.method()->is_continuation_enter_intrinsic())) {
--- 1902,62 ---
  
  oop java_lang_Thread::park_blocker(oop java_thread) {
    return java_thread->obj_field_access<MO_RELAXED>(_park_blocker_offset);
  }
  
! // Obtain stack trace for a platform of virtual thread.
  oop java_lang_Thread::async_get_stack_trace(jobject jthread, TRAPS) {
    ThreadsListHandle tlh(THREAD);
    JavaThread* java_thread = nullptr;
    oop thread_oop;
  
    bool has_java_thread = tlh.cv_internal_thread_to_JavaThread(jthread, &java_thread, &thread_oop);
!   assert((has_java_thread && thread_oop != nullptr) || !has_java_thread, "Missing Thread oop");
+   bool is_virtual = java_lang_VirtualThread::is_instance(thread_oop);
+   if (!has_java_thread && !is_virtual) {
      return nullptr;
    }
  
    class GetStackTraceHandshakeClosure : public HandshakeClosure {
    public:
      const Handle _thread_h;
      int _depth;
      GrowableArray<Method*>* _methods;
      GrowableArray<int>*     _bcis;
  
      GetStackTraceHandshakeClosure(Handle thread_h) :
!         HandshakeClosure("GetStackTraceHandshakeClosure"), _thread_h(thread_h), _depth(0),
          _methods(nullptr), _bcis(nullptr) {
      }
      ~GetStackTraceHandshakeClosure() {
        delete _methods;
        delete _bcis;
      }
  
      void do_thread(Thread* th) {
!       JavaThread* java_thread = th != nullptr ? JavaThread::cast(th) : nullptr;
!       if (java_thread != nullptr && !java_thread->has_last_Java_frame()) {
+         // stack trace is empty
          return;
        }
  
!       bool is_virtual = java_lang_VirtualThread::is_instance(_thread_h());
!       bool vthread_carrier = !is_virtual && (java_thread != nullptr) && (java_thread->vthread_continuation() != nullptr);
  
        const int max_depth = MaxJavaStackTraceDepth;
        const bool skip_hidden = !ShowHiddenFrames;
  
        // Pick minimum length that will cover most cases
        int init_length = 64;
        _methods = new (mtInternal) GrowableArray<Method*>(init_length, mtInternal);
        _bcis = new (mtInternal) GrowableArray<int>(init_length, mtInternal);
  
        int total_count = 0;
!       vframeStream vfst(java_thread != nullptr
+         ? vframeStream(java_thread, false, false, vthread_carrier)  // we don't process frames as we don't care about oops
+         : vframeStream(java_lang_VirtualThread::continuation(_thread_h())));
+       for (;
             !vfst.at_end() && (max_depth == 0 || max_depth != total_count);
             vfst.next()) {
  
          if (skip_hidden && (vfst.method()->is_hidden() ||
                              vfst.method()->is_continuation_enter_intrinsic())) {

*** 1995,13 ***
  
    // Handshake with target
    ResourceMark rm(THREAD);
    HandleMark   hm(THREAD);
    GetStackTraceHandshakeClosure gsthc(Handle(THREAD, thread_oop));
!   do {
!    Handshake::execute(&gsthc, &tlh, java_thread);
!   } while (gsthc.read_reset_retry());
  
    // Stop if no stack trace is found.
    if (gsthc._depth == 0) {
      return nullptr;
    }
--- 1975,15 ---
  
    // Handshake with target
    ResourceMark rm(THREAD);
    HandleMark   hm(THREAD);
    GetStackTraceHandshakeClosure gsthc(Handle(THREAD, thread_oop));
!   if (is_virtual) {
!     Handshake::execute(&gsthc, thread_oop);
!   } else {
+     Handshake::execute(&gsthc, &tlh, java_thread);
+   }
  
    // Stop if no stack trace is found.
    if (gsthc._depth == 0) {
      return nullptr;
    }
< prev index next >