src/hotspot/share/jfr/support/jfrThreadLocal.cpp
changeset 50113 caf115bb98ad
child 51004 162867fa0f8d
equal deleted inserted replaced
50112:7a2a740815b7 50113:caf115bb98ad
       
     1 /*
       
     2  * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  *
       
    23  */
       
    24 
       
    25 #include "precompiled.hpp"
       
    26 #include "jfr/periodic/jfrThreadCPULoadEvent.hpp"
       
    27 #include "jfr/jni/jfrJavaSupport.hpp"
       
    28 #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp"
       
    29 #include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
       
    30 #include "jfr/recorder/service/jfrOptionSet.hpp"
       
    31 #include "jfr/recorder/storage/jfrStorage.hpp"
       
    32 #include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
       
    33 #include "jfr/support/jfrThreadLocal.hpp"
       
    34 #include "memory/allocation.inline.hpp"
       
    35 #include "runtime/os.hpp"
       
    36 #include "runtime/thread.inline.hpp"
       
    37 
       
    38 /* This data structure is per thread and only accessed by the thread itself, no locking required */
       
    39 JfrThreadLocal::JfrThreadLocal() :
       
    40   _java_event_writer(NULL),
       
    41   _java_buffer(NULL),
       
    42   _native_buffer(NULL),
       
    43   _shelved_buffer(NULL),
       
    44   _stackframes(NULL),
       
    45   _trace_id(JfrTraceId::assign_thread_id()),
       
    46   _thread_cp(),
       
    47   _data_lost(0),
       
    48   _stack_trace_id(max_julong),
       
    49   _user_time(0),
       
    50   _cpu_time(0),
       
    51   _wallclock_time(os::javaTimeNanos()),
       
    52   _stack_trace_hash(0),
       
    53   _stackdepth(0),
       
    54   _entering_suspend_flag(0) {}
       
    55 
       
    56 u8 JfrThreadLocal::add_data_lost(u8 value) {
       
    57   _data_lost += value;
       
    58   return _data_lost;
       
    59 }
       
    60 
       
    61 bool JfrThreadLocal::has_thread_checkpoint() const {
       
    62   return _thread_cp.valid();
       
    63 }
       
    64 
       
    65 void JfrThreadLocal::set_thread_checkpoint(const JfrCheckpointBlobHandle& ref) {
       
    66   assert(!_thread_cp.valid(), "invariant");
       
    67   _thread_cp = ref;
       
    68 }
       
    69 
       
    70 const JfrCheckpointBlobHandle& JfrThreadLocal::thread_checkpoint() const {
       
    71   return _thread_cp;
       
    72 }
       
    73 
       
    74 void JfrThreadLocal::on_exit(JavaThread* thread) {
       
    75   JfrCheckpointManager::write_thread_checkpoint(thread);
       
    76   JfrThreadCPULoadEvent::send_event_for_thread(thread);
       
    77 }
       
    78 
       
    79 void JfrThreadLocal::on_destruct(Thread* thread) {
       
    80   JfrThreadLocal* const tl = thread->jfr_thread_local();
       
    81   if (tl->has_native_buffer()) {
       
    82     release(tl->native_buffer(), thread);
       
    83   }
       
    84   if (tl->has_java_buffer()) {
       
    85     release(tl->java_buffer(), thread);
       
    86   }
       
    87   assert(tl->shelved_buffer() == NULL, "invariant");
       
    88   if (thread->jfr_thread_local()->has_java_event_writer()) {
       
    89     JfrJavaSupport::destroy_global_jni_handle(tl->java_event_writer());
       
    90   }
       
    91   destroy_stackframes(thread);
       
    92 }
       
    93 
       
    94 JfrBuffer* JfrThreadLocal::acquire(Thread* thread, size_t size) {
       
    95   return JfrStorage::acquire_thread_local(thread, size);
       
    96 }
       
    97 
       
    98 void JfrThreadLocal::release(JfrBuffer* buffer, Thread* thread) {
       
    99   assert(buffer != NULL, "invariant");
       
   100   JfrStorage::release_thread_local(buffer, thread);
       
   101 }
       
   102 
       
   103 JfrBuffer* JfrThreadLocal::install_native_buffer() const {
       
   104   assert(!has_native_buffer(), "invariant");
       
   105   _native_buffer = acquire(Thread::current());
       
   106   return _native_buffer;
       
   107 }
       
   108 
       
   109 JfrBuffer* JfrThreadLocal::install_java_buffer() const {
       
   110   assert(!has_java_buffer(), "invariant");
       
   111   assert(!has_java_event_writer(), "invariant");
       
   112   _java_buffer = acquire(Thread::current());
       
   113   return _java_buffer;
       
   114 }
       
   115 
       
   116 JfrStackFrame* JfrThreadLocal::install_stackframes() const {
       
   117   assert(_stackframes == NULL, "invariant");
       
   118   _stackdepth = (u4)JfrOptionSet::stackdepth();
       
   119   guarantee(_stackdepth > 0, "Stackdepth must be > 0");
       
   120   _stackframes = NEW_C_HEAP_ARRAY(JfrStackFrame, _stackdepth, mtTracing);
       
   121   return _stackframes;
       
   122 }
       
   123 
       
   124 void JfrThreadLocal::destroy_stackframes(Thread* thread) {
       
   125   assert(thread != NULL, "invariant");
       
   126   JfrStackFrame* frames = thread->jfr_thread_local()->stackframes();
       
   127   if (frames != NULL) {
       
   128     FREE_C_HEAP_ARRAY(JfrStackFrame, frames);
       
   129     thread->jfr_thread_local()->set_stackframes(NULL);
       
   130   }
       
   131 }