8210024: JFR calls virtual is_Java_thread from ~Thread()

Thu, 15 Nov 2018 11:10:04 +0100

author
mgronlun
date
Thu, 15 Nov 2018 11:10:04 +0100
changeset 9868
69fb91513217
parent 9867
150ab470bf7f
child 9869
a5e7fde5ba80

8210024: JFR calls virtual is_Java_thread from ~Thread()
Reviewed-by: kbarrett, dholmes, dcubed, egahlin

src/share/vm/jfr/jfr.cpp file | annotate | diff | comparison | revisions
src/share/vm/jfr/jfr.hpp file | annotate | diff | comparison | revisions
src/share/vm/jfr/support/jfrThreadLocal.cpp file | annotate | diff | comparison | revisions
src/share/vm/jfr/support/jfrThreadLocal.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/thread.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/jfr/jfr.cpp	Wed Dec 05 16:40:12 2018 +0100
     1.2 +++ b/src/share/vm/jfr/jfr.cpp	Thu Nov 15 11:10:04 2018 +0100
     1.3 @@ -63,13 +63,17 @@
     1.4    }
     1.5  }
     1.6  
     1.7 -void Jfr::on_thread_exit(JavaThread* thread) {
     1.8 -  JfrThreadLocal::on_exit(thread);
     1.9 +void Jfr::on_thread_start(Thread* t) {
    1.10 +  JfrThreadLocal::on_start(t);
    1.11  }
    1.12  
    1.13 -void Jfr::on_thread_destruct(Thread* thread) {
    1.14 -  if (JfrRecorder::is_created()) {
    1.15 -    JfrThreadLocal::on_destruct(thread);
    1.16 +void Jfr::on_thread_exit(Thread* t) {
    1.17 +  JfrThreadLocal::on_exit(t);
    1.18 +}
    1.19 +
    1.20 +void Jfr::on_java_thread_dismantle(JavaThread* jt) {
    1.21 +  if (JfrRecorder::is_recording()) {
    1.22 +    JfrCheckpointManager::write_thread_checkpoint(jt);
    1.23    }
    1.24  }
    1.25  
     2.1 --- a/src/share/vm/jfr/jfr.hpp	Wed Dec 05 16:40:12 2018 +0100
     2.2 +++ b/src/share/vm/jfr/jfr.hpp	Thu Nov 15 11:10:04 2018 +0100
     2.3 @@ -46,8 +46,9 @@
     2.4    static void on_vm_init();
     2.5    static void on_vm_start();
     2.6    static void on_unloading_classes();
     2.7 -  static void on_thread_exit(JavaThread* thread);
     2.8 -  static void on_thread_destruct(Thread* thread);
     2.9 +  static void on_thread_start(Thread* thread);
    2.10 +  static void on_thread_exit(Thread* thread);
    2.11 +  static void on_java_thread_dismantle(JavaThread* jt);
    2.12    static void on_vm_shutdown(bool exception_handler = false);
    2.13    static bool on_flight_recorder_option(const JavaVMOption** option, char* delimiter);
    2.14    static bool on_start_flight_recording_option(const JavaVMOption** option, char* delimiter);
     3.1 --- a/src/share/vm/jfr/support/jfrThreadLocal.cpp	Wed Dec 05 16:40:12 2018 +0100
     3.2 +++ b/src/share/vm/jfr/support/jfrThreadLocal.cpp	Thu Nov 15 11:10:04 2018 +0100
     3.3 @@ -23,6 +23,7 @@
     3.4   */
     3.5  
     3.6  #include "precompiled.hpp"
     3.7 +#include "jfr/jfrEvents.hpp"
     3.8  #include "jfr/jni/jfrJavaSupport.hpp"
     3.9  #include "jfr/periodic/jfrThreadCPULoadEvent.hpp"
    3.10  #include "jfr/recorder/jfrRecorder.hpp"
    3.11 @@ -35,6 +36,7 @@
    3.12  #include "memory/allocation.inline.hpp"
    3.13  #include "runtime/os.hpp"
    3.14  #include "runtime/thread.inline.hpp"
    3.15 +#include "utilities/sizes.hpp"
    3.16  
    3.17  /* This data structure is per thread and only accessed by the thread itself, no locking required */
    3.18  JfrThreadLocal::JfrThreadLocal() :
    3.19 @@ -73,53 +75,76 @@
    3.20    return _thread_cp;
    3.21  }
    3.22  
    3.23 -void JfrThreadLocal::set_dead() {
    3.24 -  assert(!is_dead(), "invariant");
    3.25 -  _dead = true;
    3.26 +static void send_java_thread_start_event(JavaThread* jt) {
    3.27 +  EventThreadStart event;
    3.28 +  event.set_thread(jt->jfr_thread_local()->thread_id());
    3.29 +  event.commit();
    3.30  }
    3.31  
    3.32 -void JfrThreadLocal::on_exit(JavaThread* thread) {
    3.33 +void JfrThreadLocal::on_start(Thread* t) {
    3.34 +  assert(t != NULL, "invariant");
    3.35 +  assert(Thread::current() == t, "invariant");
    3.36    if (JfrRecorder::is_recording()) {
    3.37 -    JfrCheckpointManager::write_thread_checkpoint(thread);
    3.38 -    JfrThreadCPULoadEvent::send_event_for_thread(thread);
    3.39 +    if (t->is_Java_thread()) {
    3.40 +      send_java_thread_start_event((JavaThread*)t);
    3.41 +    }
    3.42    }
    3.43 -  thread->jfr_thread_local()->set_dead();
    3.44  }
    3.45  
    3.46 -void JfrThreadLocal::on_destruct(Thread* thread) {
    3.47 -  JfrThreadLocal* const tl = thread->jfr_thread_local();
    3.48 +static void send_java_thread_end_events(traceid id, JavaThread* jt) {
    3.49 +  assert(jt != NULL, "invariant");
    3.50 +  assert(Thread::current() == jt, "invariant");
    3.51 +  assert(jt->jfr_thread_local()->trace_id() == id, "invariant");
    3.52 +  EventThreadEnd event;
    3.53 +  event.set_thread(id);
    3.54 +  event.commit();
    3.55 +  JfrThreadCPULoadEvent::send_event_for_thread(jt);
    3.56 +}
    3.57 +
    3.58 +void JfrThreadLocal::release(JfrThreadLocal* tl, Thread* t) {
    3.59 +  assert(tl != NULL, "invariant");
    3.60 +  assert(t != NULL, "invariant");
    3.61 +  assert(Thread::current() == t, "invariant");
    3.62 +  assert(!tl->is_dead(), "invariant");
    3.63 +  assert(tl->shelved_buffer() == NULL, "invariant");
    3.64    if (tl->has_native_buffer()) {
    3.65 -    release(tl->native_buffer(), thread);
    3.66 +    JfrStorage::release_thread_local(tl->native_buffer(), t);
    3.67    }
    3.68    if (tl->has_java_buffer()) {
    3.69 -    release(tl->java_buffer(), thread);
    3.70 +    JfrStorage::release_thread_local(tl->java_buffer(), t);
    3.71    }
    3.72 -  assert(tl->shelved_buffer() == NULL, "invariant");
    3.73 -  if (thread->jfr_thread_local()->has_java_event_writer()) {
    3.74 +  if (tl->has_java_event_writer()) {
    3.75 +    assert(t->is_Java_thread(), "invariant");
    3.76      JfrJavaSupport::destroy_global_jni_handle(tl->java_event_writer());
    3.77    }
    3.78 -  destroy_stackframes(thread);
    3.79 +  if (tl->_stackframes != NULL) {
    3.80 +    FREE_C_HEAP_ARRAY(JfrStackFrame, tl->_stackframes, mtTracing);
    3.81 +  }
    3.82 +  tl->_dead = true;
    3.83  }
    3.84  
    3.85 -JfrBuffer* JfrThreadLocal::acquire(Thread* thread, size_t size) {
    3.86 -  return JfrStorage::acquire_thread_local(thread, size);
    3.87 -}
    3.88 -
    3.89 -void JfrThreadLocal::release(JfrBuffer* buffer, Thread* thread) {
    3.90 -  assert(buffer != NULL, "invariant");
    3.91 -  JfrStorage::release_thread_local(buffer, thread);
    3.92 +void JfrThreadLocal::on_exit(Thread* t) {
    3.93 +  assert(t != NULL, "invariant");
    3.94 +  JfrThreadLocal * const tl = t->jfr_thread_local();
    3.95 +  assert(!tl->is_dead(), "invariant");
    3.96 +  if (JfrRecorder::is_recording()) {
    3.97 +    if (t->is_Java_thread()) {
    3.98 +      send_java_thread_end_events(tl->thread_id(), (JavaThread*)t);
    3.99 +    }
   3.100 +  }
   3.101 +  release(tl, Thread::current()); // because it could be that Thread::current() != t
   3.102  }
   3.103  
   3.104  JfrBuffer* JfrThreadLocal::install_native_buffer() const {
   3.105    assert(!has_native_buffer(), "invariant");
   3.106 -  _native_buffer = acquire(Thread::current());
   3.107 +  _native_buffer = JfrStorage::acquire_thread_local(Thread::current());
   3.108    return _native_buffer;
   3.109  }
   3.110  
   3.111  JfrBuffer* JfrThreadLocal::install_java_buffer() const {
   3.112    assert(!has_java_buffer(), "invariant");
   3.113    assert(!has_java_event_writer(), "invariant");
   3.114 -  _java_buffer = acquire(Thread::current());
   3.115 +  _java_buffer = JfrStorage::acquire_thread_local(Thread::current());
   3.116    return _java_buffer;
   3.117  }
   3.118  
   3.119 @@ -131,11 +156,10 @@
   3.120    return _stackframes;
   3.121  }
   3.122  
   3.123 -void JfrThreadLocal::destroy_stackframes(Thread* thread) {
   3.124 -  assert(thread != NULL, "invariant");
   3.125 -  JfrStackFrame* frames = thread->jfr_thread_local()->stackframes();
   3.126 -  if (frames != NULL) {
   3.127 -    FREE_C_HEAP_ARRAY(JfrStackFrame, frames, mtTracing);
   3.128 -    thread->jfr_thread_local()->set_stackframes(NULL);
   3.129 -  }
   3.130 +ByteSize JfrThreadLocal::trace_id_offset() {
   3.131 +  return in_ByteSize(offset_of(JfrThreadLocal, _trace_id));
   3.132  }
   3.133 +
   3.134 +ByteSize JfrThreadLocal::java_event_writer_offset() {
   3.135 +  return in_ByteSize(offset_of(JfrThreadLocal, _java_event_writer));
   3.136 +}
     4.1 --- a/src/share/vm/jfr/support/jfrThreadLocal.hpp	Wed Dec 05 16:40:12 2018 +0100
     4.2 +++ b/src/share/vm/jfr/support/jfrThreadLocal.hpp	Thu Nov 15 11:10:04 2018 +0100
     4.3 @@ -27,11 +27,11 @@
     4.4  
     4.5  #include "jfr/recorder/checkpoint/jfrCheckpointBlob.hpp"
     4.6  #include "jfr/utilities/jfrTypes.hpp"
     4.7 -#include "utilities/sizes.hpp"
     4.8  
     4.9  class JavaThread;
    4.10  class JfrBuffer;
    4.11  class JfrStackFrame;
    4.12 +class Thread;
    4.13  
    4.14  class JfrThreadLocal {
    4.15   private:
    4.16 @@ -56,7 +56,7 @@
    4.17    JfrBuffer* install_java_buffer() const;
    4.18    JfrStackFrame* install_stackframes() const;
    4.19  
    4.20 -  void set_dead();
    4.21 +  static void release(JfrThreadLocal* tl, Thread* t);
    4.22  
    4.23   public:
    4.24    JfrThreadLocal();
    4.25 @@ -213,20 +213,12 @@
    4.26    void set_thread_checkpoint(const JfrCheckpointBlobHandle& handle);
    4.27    const JfrCheckpointBlobHandle& thread_checkpoint() const;
    4.28  
    4.29 -  static JfrBuffer* acquire(Thread* t, size_t size = 0);
    4.30 -  static void release(JfrBuffer* buffer, Thread* t);
    4.31 -  static void destroy_stackframes(Thread* t);
    4.32 -  static void on_exit(JavaThread* t);
    4.33 -  static void on_destruct(Thread* t);
    4.34 +  static void on_start(Thread* t);
    4.35 +  static void on_exit(Thread* t);
    4.36  
    4.37    // Code generation
    4.38 -  static ByteSize trace_id_offset() {
    4.39 -    return in_ByteSize(offset_of(JfrThreadLocal, _trace_id));
    4.40 -  }
    4.41 -
    4.42 -  static ByteSize java_event_writer_offset() {
    4.43 -    return in_ByteSize(offset_of(JfrThreadLocal, _java_event_writer));
    4.44 -  }
    4.45 +  static ByteSize trace_id_offset();
    4.46 +  static ByteSize java_event_writer_offset();
    4.47  };
    4.48  
    4.49  #endif // SHARE_VM_JFR_SUPPORT_JFRTHREADLOCAL_HPP
     5.1 --- a/src/share/vm/runtime/thread.cpp	Wed Dec 05 16:40:12 2018 +0100
     5.2 +++ b/src/share/vm/runtime/thread.cpp	Thu Nov 15 11:10:04 2018 +0100
     5.3 @@ -33,7 +33,6 @@
     5.4  #include "interpreter/linkResolver.hpp"
     5.5  #include "interpreter/oopMapCache.hpp"
     5.6  #include "jfr/jfrEvents.hpp"
     5.7 -#include "jfr/support/jfrThreadId.hpp"
     5.8  #include "jvmtifiles/jvmtiEnv.hpp"
     5.9  #include "memory/gcLocker.inline.hpp"
    5.10  #include "memory/metaspaceShared.hpp"
    5.11 @@ -345,8 +344,6 @@
    5.12    // Reclaim the objectmonitors from the omFreeList of the moribund thread.
    5.13    ObjectSynchronizer::omFlush (this) ;
    5.14  
    5.15 -  JFR_ONLY(Jfr::on_thread_destruct(this);)
    5.16 -
    5.17    // stack_base can be NULL if the thread is never started or exited before
    5.18    // record_stack_base_and_size called. Although, we would like to ensure
    5.19    // that all started threads do call record_stack_base_and_size(), there is
    5.20 @@ -1215,6 +1212,7 @@
    5.21  }
    5.22  
    5.23  NamedThread::~NamedThread() {
    5.24 +  JFR_ONLY(Jfr::on_thread_exit(this);)
    5.25    if (_name != NULL) {
    5.26      FREE_C_HEAP_ARRAY(char, _name, mtThread);
    5.27      _name = NULL;
    5.28 @@ -1672,11 +1670,7 @@
    5.29      JvmtiExport::post_thread_start(this);
    5.30    }
    5.31  
    5.32 -  EventThreadStart event;
    5.33 -  if (event.should_commit()) {
    5.34 -    event.set_thread(JFR_THREAD_ID(this));
    5.35 -     event.commit();
    5.36 -  }
    5.37 +  JFR_ONLY(Jfr::on_thread_start(this);)
    5.38  
    5.39    // We call another function to do the rest so we are sure that the stack addresses used
    5.40    // from there will be lower than the stack base just computed
    5.41 @@ -1803,17 +1797,7 @@
    5.42          }
    5.43        }
    5.44      }
    5.45 -
    5.46 -    // Called before the java thread exit since we want to read info
    5.47 -    // from java_lang_Thread object
    5.48 -    EventThreadEnd event;
    5.49 -    if (event.should_commit()) {
    5.50 -      event.set_thread(JFR_THREAD_ID(this));
    5.51 -      event.commit();
    5.52 -    }
    5.53 -
    5.54 -    // Call after last event on thread
    5.55 -    JFR_ONLY(Jfr::on_thread_exit(this);)
    5.56 +    JFR_ONLY(Jfr::on_java_thread_dismantle(this);)
    5.57  
    5.58      // Call Thread.exit(). We try 3 times in case we got another Thread.stop during
    5.59      // the execution of the method. If that is not enough, then we don't really care. Thread.stop
    5.60 @@ -1890,6 +1874,7 @@
    5.61    // These things needs to be done while we are still a Java Thread. Make sure that thread
    5.62    // is in a consistent state, in case GC happens
    5.63    assert(_privileged_stack_top == NULL, "must be NULL when we get here");
    5.64 +  JFR_ONLY(Jfr::on_thread_exit(this);)
    5.65  
    5.66    if (active_handles() != NULL) {
    5.67      JNIHandleBlock* block = active_handles();

mercurial