< prev index next >

src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp

Print this page
*** 161,11 ***
  
    if (JfrOptionSet::sample_protection()) {
      OSThreadSamplerCallback cb(*this, context);
      os::ThreadCrashProtection crash_protection;
      if (!crash_protection.call(cb)) {
!       log_error(jfr)("Thread method sampler crashed");
      }
    } else {
      protected_task(context);
    }
  }
--- 161,11 ---
  
    if (JfrOptionSet::sample_protection()) {
      OSThreadSamplerCallback cb(*this, context);
      os::ThreadCrashProtection crash_protection;
      if (!crash_protection.call(cb)) {
!       log_debug(jfr)("Thread method sampler crashed");
      }
    } else {
      protected_task(context);
    }
  }

*** 173,28 ***
  /*
  * From this method and down the call tree we attempt to protect against crashes
  * using a signal handler / __try block. Don't take locks, rely on destructors or
  * leave memory (in case of signal / exception) in an inconsistent state. */
  void OSThreadSampler::protected_task(const os::SuspendedThreadTaskContext& context) {
!   JavaThread* jth = JavaThread::cast(context.thread());
    // Skip sample if we signaled a thread that moved to other state
!   if (!thread_state_in_java(jth)) {
      return;
    }
!   JfrGetCallTrace trace(true, jth);
    frame topframe;
    if (trace.get_topframe(context.ucontext(), topframe)) {
!     if (_stacktrace.record_thread(*jth, topframe)) {
        /* If we managed to get a topframe and a stacktrace, create an event
        * and put it into our array. We can't call Jfr::_stacktraces.add()
        * here since it would allocate memory using malloc. Doing so while
        * the stopped thread is inside malloc would deadlock. */
        _success = true;
        EventExecutionSample *ev = _closure.next_event();
        ev->set_starttime(_suspend_time);
        ev->set_endtime(_suspend_time); // fake to not take an end time
!       ev->set_sampledThread(JFR_THREAD_ID(jth));
        ev->set_state(static_cast<u8>(java_lang_Thread::get_thread_status(_thread_oop)));
      }
    }
  }
  
--- 173,29 ---
  /*
  * From this method and down the call tree we attempt to protect against crashes
  * using a signal handler / __try block. Don't take locks, rely on destructors or
  * leave memory (in case of signal / exception) in an inconsistent state. */
  void OSThreadSampler::protected_task(const os::SuspendedThreadTaskContext& context) {
!   JavaThread* const jt = JavaThread::cast(context.thread());
    // Skip sample if we signaled a thread that moved to other state
!   if (!thread_state_in_java(jt)) {
      return;
    }
!   JfrGetCallTrace trace(true, jt);
    frame topframe;
    if (trace.get_topframe(context.ucontext(), topframe)) {
!     bool virtual_thread;
+     if (_stacktrace.record_async(jt, topframe, &virtual_thread)) {
        /* If we managed to get a topframe and a stacktrace, create an event
        * and put it into our array. We can't call Jfr::_stacktraces.add()
        * here since it would allocate memory using malloc. Doing so while
        * the stopped thread is inside malloc would deadlock. */
        _success = true;
        EventExecutionSample *ev = _closure.next_event();
        ev->set_starttime(_suspend_time);
        ev->set_endtime(_suspend_time); // fake to not take an end time
!       ev->set_sampledThread(virtual_thread ? JFR_THREAD_ID(jt) : JFR_VM_THREAD_ID(jt));
        ev->set_state(static_cast<u8>(java_lang_Thread::get_thread_status(_thread_oop)));
      }
    }
  }
  

*** 217,14 ***
    oop _thread_oop;
    JfrStackTrace _stacktrace;
    bool _success;
  };
  
! static void write_native_event(JfrThreadSampleClosure& closure, JavaThread* jt, oop thread_oop) {
    EventNativeMethodSample *ev = closure.next_event_native();
    ev->set_starttime(JfrTicks::now());
!   ev->set_sampledThread(JFR_THREAD_ID(jt));
    ev->set_state(static_cast<u8>(java_lang_Thread::get_thread_status(thread_oop)));
  }
  
  void JfrNativeSamplerCallback::call() {
    // When a thread is only attach it will be native without a last java frame
--- 218,14 ---
    oop _thread_oop;
    JfrStackTrace _stacktrace;
    bool _success;
  };
  
! static void write_native_event(JfrThreadSampleClosure& closure, bool virtual_thread, JavaThread* jt, oop thread_oop) {
    EventNativeMethodSample *ev = closure.next_event_native();
    ev->set_starttime(JfrTicks::now());
!   ev->set_sampledThread(virtual_thread ? JFR_THREAD_ID(jt) : JFR_VM_THREAD_ID(jt));
    ev->set_state(static_cast<u8>(java_lang_Thread::get_thread_status(thread_oop)));
  }
  
  void JfrNativeSamplerCallback::call() {
    // When a thread is only attach it will be native without a last java frame

*** 241,13 ***
    }
    if (method == NULL) {
      return;
    }
    topframe = first_java_frame;
!   _success = _stacktrace.record_thread(*_jt, topframe);
    if (_success) {
!     write_native_event(_closure, _jt, _thread_oop);
    }
  }
  
  bool JfrThreadSampleClosure::sample_thread_in_java(JavaThread* thread, JfrStackFrame* frames, u4 max_frames) {
    OSThreadSampler sampler(thread, *this, frames, max_frames);
--- 242,14 ---
    }
    if (method == NULL) {
      return;
    }
    topframe = first_java_frame;
!   bool virtual_thread;
+   _success = _stacktrace.record_async(_jt, topframe, &virtual_thread);
    if (_success) {
!     write_native_event(_closure, virtual_thread, _jt, _thread_oop);
    }
  }
  
  bool JfrThreadSampleClosure::sample_thread_in_java(JavaThread* thread, JfrStackFrame* frames, u4 max_frames) {
    OSThreadSampler sampler(thread, *this, frames, max_frames);
< prev index next >