src/hotspot/share/jfr/support/jfrThreadLocal.cpp
changeset 52569 1a534c7926cc
parent 51004 162867fa0f8d
child 55571 49102ba8cf14
child 57360 5d043a159d5c
child 58678 9cf78a70fa4f
equal deleted inserted replaced
52568:40474b7105f4 52569:1a534c7926cc
    21  * questions.
    21  * questions.
    22  *
    22  *
    23  */
    23  */
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
       
    26 #include "jfr/jfrEvents.hpp"
    26 #include "jfr/jni/jfrJavaSupport.hpp"
    27 #include "jfr/jni/jfrJavaSupport.hpp"
    27 #include "jfr/periodic/jfrThreadCPULoadEvent.hpp"
    28 #include "jfr/periodic/jfrThreadCPULoadEvent.hpp"
    28 #include "jfr/recorder/jfrRecorder.hpp"
    29 #include "jfr/recorder/jfrRecorder.hpp"
    29 #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp"
    30 #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp"
    30 #include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
    31 #include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
    33 #include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
    34 #include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
    34 #include "jfr/support/jfrThreadLocal.hpp"
    35 #include "jfr/support/jfrThreadLocal.hpp"
    35 #include "memory/allocation.inline.hpp"
    36 #include "memory/allocation.inline.hpp"
    36 #include "runtime/os.hpp"
    37 #include "runtime/os.hpp"
    37 #include "runtime/thread.inline.hpp"
    38 #include "runtime/thread.inline.hpp"
       
    39 #include "utilities/sizes.hpp"
    38 
    40 
    39 /* This data structure is per thread and only accessed by the thread itself, no locking required */
    41 /* This data structure is per thread and only accessed by the thread itself, no locking required */
    40 JfrThreadLocal::JfrThreadLocal() :
    42 JfrThreadLocal::JfrThreadLocal() :
    41   _java_event_writer(NULL),
    43   _java_event_writer(NULL),
    42   _java_buffer(NULL),
    44   _java_buffer(NULL),
    71 
    73 
    72 const JfrCheckpointBlobHandle& JfrThreadLocal::thread_checkpoint() const {
    74 const JfrCheckpointBlobHandle& JfrThreadLocal::thread_checkpoint() const {
    73   return _thread_cp;
    75   return _thread_cp;
    74 }
    76 }
    75 
    77 
    76 void JfrThreadLocal::set_dead() {
    78 static void send_java_thread_start_event(JavaThread* jt) {
    77   assert(!is_dead(), "invariant");
    79   EventThreadStart event;
    78   _dead = true;
    80   event.set_thread(jt->jfr_thread_local()->thread_id());
       
    81   event.commit();
    79 }
    82 }
    80 
    83 
    81 void JfrThreadLocal::on_exit(JavaThread* thread) {
    84 void JfrThreadLocal::on_start(Thread* t) {
       
    85   assert(t != NULL, "invariant");
       
    86   assert(Thread::current() == t, "invariant");
    82   if (JfrRecorder::is_recording()) {
    87   if (JfrRecorder::is_recording()) {
    83     JfrCheckpointManager::write_thread_checkpoint(thread);
    88     if (t->is_Java_thread()) {
    84     JfrThreadCPULoadEvent::send_event_for_thread(thread);
    89       send_java_thread_start_event((JavaThread*)t);
       
    90     }
    85   }
    91   }
    86   thread->jfr_thread_local()->set_dead();
       
    87 }
    92 }
    88 
    93 
    89 void JfrThreadLocal::on_destruct(Thread* thread) {
    94 static void send_java_thread_end_events(traceid id, JavaThread* jt) {
    90   JfrThreadLocal* const tl = thread->jfr_thread_local();
    95   assert(jt != NULL, "invariant");
       
    96   assert(Thread::current() == jt, "invariant");
       
    97   assert(jt->jfr_thread_local()->trace_id() == id, "invariant");
       
    98   EventThreadEnd event;
       
    99   event.set_thread(id);
       
   100   event.commit();
       
   101   JfrThreadCPULoadEvent::send_event_for_thread(jt);
       
   102 }
       
   103 
       
   104 void JfrThreadLocal::release(JfrThreadLocal* tl, Thread* t) {
       
   105   assert(tl != NULL, "invariant");
       
   106   assert(t != NULL, "invariant");
       
   107   assert(Thread::current() == t, "invariant");
       
   108   assert(!tl->is_dead(), "invariant");
       
   109   assert(tl->shelved_buffer() == NULL, "invariant");
    91   if (tl->has_native_buffer()) {
   110   if (tl->has_native_buffer()) {
    92     release(tl->native_buffer(), thread);
   111     JfrStorage::release_thread_local(tl->native_buffer(), t);
    93   }
   112   }
    94   if (tl->has_java_buffer()) {
   113   if (tl->has_java_buffer()) {
    95     release(tl->java_buffer(), thread);
   114     JfrStorage::release_thread_local(tl->java_buffer(), t);
    96   }
   115   }
    97   assert(tl->shelved_buffer() == NULL, "invariant");
   116   if (tl->has_java_event_writer()) {
    98   if (thread->jfr_thread_local()->has_java_event_writer()) {
   117     assert(t->is_Java_thread(), "invariant");
    99     JfrJavaSupport::destroy_global_jni_handle(tl->java_event_writer());
   118     JfrJavaSupport::destroy_global_jni_handle(tl->java_event_writer());
   100   }
   119   }
   101   destroy_stackframes(thread);
   120   if (tl->_stackframes != NULL) {
       
   121     FREE_C_HEAP_ARRAY(JfrStackFrame, tl->_stackframes);
       
   122   }
       
   123   tl->_dead = true;
   102 }
   124 }
   103 
   125 
   104 JfrBuffer* JfrThreadLocal::acquire(Thread* thread, size_t size) {
   126 void JfrThreadLocal::on_exit(Thread* t) {
   105   return JfrStorage::acquire_thread_local(thread, size);
   127   assert(t != NULL, "invariant");
   106 }
   128   JfrThreadLocal * const tl = t->jfr_thread_local();
   107 
   129   assert(!tl->is_dead(), "invariant");
   108 void JfrThreadLocal::release(JfrBuffer* buffer, Thread* thread) {
   130   if (JfrRecorder::is_recording()) {
   109   assert(buffer != NULL, "invariant");
   131     if (t->is_Java_thread()) {
   110   JfrStorage::release_thread_local(buffer, thread);
   132       send_java_thread_end_events(tl->thread_id(), (JavaThread*)t);
       
   133     }
       
   134   }
       
   135   release(tl, Thread::current()); // because it could be that Thread::current() != t
   111 }
   136 }
   112 
   137 
   113 JfrBuffer* JfrThreadLocal::install_native_buffer() const {
   138 JfrBuffer* JfrThreadLocal::install_native_buffer() const {
   114   assert(!has_native_buffer(), "invariant");
   139   assert(!has_native_buffer(), "invariant");
   115   _native_buffer = acquire(Thread::current());
   140   _native_buffer = JfrStorage::acquire_thread_local(Thread::current());
   116   return _native_buffer;
   141   return _native_buffer;
   117 }
   142 }
   118 
   143 
   119 JfrBuffer* JfrThreadLocal::install_java_buffer() const {
   144 JfrBuffer* JfrThreadLocal::install_java_buffer() const {
   120   assert(!has_java_buffer(), "invariant");
   145   assert(!has_java_buffer(), "invariant");
   121   assert(!has_java_event_writer(), "invariant");
   146   assert(!has_java_event_writer(), "invariant");
   122   _java_buffer = acquire(Thread::current());
   147   _java_buffer = JfrStorage::acquire_thread_local(Thread::current());
   123   return _java_buffer;
   148   return _java_buffer;
   124 }
   149 }
   125 
   150 
   126 JfrStackFrame* JfrThreadLocal::install_stackframes() const {
   151 JfrStackFrame* JfrThreadLocal::install_stackframes() const {
   127   assert(_stackframes == NULL, "invariant");
   152   assert(_stackframes == NULL, "invariant");
   129   guarantee(_stackdepth > 0, "Stackdepth must be > 0");
   154   guarantee(_stackdepth > 0, "Stackdepth must be > 0");
   130   _stackframes = NEW_C_HEAP_ARRAY(JfrStackFrame, _stackdepth, mtTracing);
   155   _stackframes = NEW_C_HEAP_ARRAY(JfrStackFrame, _stackdepth, mtTracing);
   131   return _stackframes;
   156   return _stackframes;
   132 }
   157 }
   133 
   158 
   134 void JfrThreadLocal::destroy_stackframes(Thread* thread) {
   159 ByteSize JfrThreadLocal::trace_id_offset() {
   135   assert(thread != NULL, "invariant");
   160   return in_ByteSize(offset_of(JfrThreadLocal, _trace_id));
   136   JfrStackFrame* frames = thread->jfr_thread_local()->stackframes();
       
   137   if (frames != NULL) {
       
   138     FREE_C_HEAP_ARRAY(JfrStackFrame, frames);
       
   139     thread->jfr_thread_local()->set_stackframes(NULL);
       
   140   }
       
   141 }
   161 }
       
   162 
       
   163 ByteSize JfrThreadLocal::java_event_writer_offset() {
       
   164   return in_ByteSize(offset_of(JfrThreadLocal, _java_event_writer));
       
   165 }