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 #ifndef SHARE_VM_TRACE_TRACEMACROS_HPP
  26 #define SHARE_VM_TRACE_TRACEMACROS_HPP
  27 
  28 #include "utilities/macros.hpp"
  29 
  30 typedef u8 traceid;
  31 
  32 #if INCLUDE_TRACE
  33 
  34 #define JDK_JFR_EVENT_SUBKLASS 16
  35 #define JDK_JFR_EVENT_KLASS 32
  36 #define EVENT_HOST_KLASS 64
  37 #define IS_EVENT_KLASS(ptr) (((ptr)->trace_id() & (JDK_JFR_EVENT_KLASS | JDK_JFR_EVENT_SUBKLASS)) != 0)
  38 #define IS_JDK_JFR_EVENT_SUBKLASS(ptr) (((ptr)->trace_id() & (JDK_JFR_EVENT_SUBKLASS)) != 0)
  39 
  40 #define USED_BIT 1
  41 #define METHOD_USED_BIT (USED_BIT << 2)
  42 #define EPOCH_1_SHIFT 0
  43 #define EPOCH_2_SHIFT 1
  44 #define LEAKP_SHIFT 8
  45 
  46 #define USED_EPOCH_1_BIT (USED_BIT << EPOCH_1_SHIFT)
  47 #define USED_EPOCH_2_BIT (USED_BIT << EPOCH_2_SHIFT)
  48 #define LEAKP_USED_EPOCH_1_BIT (USED_EPOCH_1_BIT << LEAKP_SHIFT)
  49 #define LEAKP_USED_EPOCH_2_BIT (USED_EPOCH_2_BIT << LEAKP_SHIFT)
  50 #define METHOD_USED_EPOCH_1_BIT (METHOD_USED_BIT << EPOCH_1_SHIFT)
  51 #define METHOD_USED_EPOCH_2_BIT (METHOD_USED_BIT << EPOCH_2_SHIFT)
  52 #define METHOD_AND_CLASS_IN_USE_BITS (METHOD_USED_BIT | USED_BIT)
  53 #define METHOD_AND_CLASS_IN_USE_EPOCH_1_BITS (METHOD_AND_CLASS_IN_USE_BITS << EPOCH_1_SHIFT)
  54 #define METHOD_AND_CLASS_IN_USE_EPOCH_2_BITS (METHOD_AND_CLASS_IN_USE_BITS << EPOCH_2_SHIFT)
  55 
  56 #define ANY_USED_BITS (USED_EPOCH_2_BIT         | \
  57                        USED_EPOCH_1_BIT         | \
  58                        METHOD_USED_EPOCH_2_BIT  | \
  59                        METHOD_USED_EPOCH_1_BIT  | \
  60                        LEAKP_USED_EPOCH_2_BIT   | \
  61                        LEAKP_USED_EPOCH_1_BIT)
  62 
  63 #define TRACE_ID_META_BITS (EVENT_HOST_KLASS | JDK_JFR_EVENT_KLASS | JDK_JFR_EVENT_SUBKLASS | ANY_USED_BITS)
  64 #define EVENT_THREAD_EXIT(thread) JfrBackend::on_javathread_exit(thread)
  65 #define EVENT_THREAD_DESTRUCT(thread) JfrBackend::on_thread_destruct(thread)
  66 #define TRACE_SUSPEND_THREAD(thread) JfrBackend::on_javathread_suspend(thread)
  67 #define TRACE_INIT_ID(data) JfrTraceId::assign(data);
  68 #define TRACE_REMOVE_ID(k) JfrTraceId::remove(k);
  69 #define TRACE_RESTORE_ID(k) JfrTraceId::restore(k);
  70 #define TRACE_KLASS_CREATION(k, p, t) if (IS_EVENT_KLASS(k)) JfrEventClassTransformer::on_klass_creation(k, p, t);
  71 #define THREAD_TRACE_ID(thread) thread->trace_data()->thread_id()
  72 #define TRACE_DEFINE_TRACE_ID_FIELD mutable traceid _trace_id
  73 
  74 #define TRACE_DEFINE_TRACE_ID_METHODS \
  75   traceid trace_id() const { return _trace_id; } \
  76   traceid* const trace_id_addr() const { return &_trace_id; } \
  77   void set_trace_id(traceid id) const { _trace_id = id; }
  78 
  79 class TraceFlag {
  80  private:
  81   mutable jbyte _flags;
  82  public:
  83   TraceFlag() : _flags(0) {}
  84   explicit TraceFlag(jbyte flags) : _flags(flags) {}
  85   void set_flag(jbyte flag) const {
  86     _flags |= flag;
  87   }
  88   void clear_flag(jbyte flag) const {
  89     _flags &= (~flag);
  90   }
  91   jbyte flags() const { return _flags; }
  92   bool is_set(jbyte flag) const {
  93     return (_flags & flag) != 0;
  94   }
  95   jbyte* const flags_addr() const{
  96     return &_flags;
  97   }
  98 };
  99 
 100 #define TRACE_DEFINE_FLAG mutable TraceFlag _trace_flags
 101 #define TRACE_DEFINE_FLAG_ACCESSOR                 \
 102   void set_trace_flag(jbyte flag) const {          \
 103     _trace_flags.set_flag(flag);                   \
 104   }                                                \
 105   jbyte trace_flags() const {                      \
 106     return _trace_flags.flags();                   \
 107   }                                                \
 108   bool is_trace_flag_set(jbyte flag) const {       \
 109     return _trace_flags.is_set(flag);              \
 110   }                                                \
 111   jbyte* const trace_flags_addr() const {          \
 112     return _trace_flags.flags_addr();              \
 113   }
 114 
 115 #define TRACE_FLUSH(E, thread) JfrEventConditionalFlush<E> flush(thread);
 116 #define TRACE_STACKTRACE_MARK(thread) JfrStackTraceMark mark(thread);
 117 #define TRACE_FLUSH_WITH_STACKTRACE(E, thread) JfrEventConditionalFlushWithStacktrace<E> flush(thread);
 118 
 119 #define TRACE_DATA JfrThreadData
 120 #define TRACE_START() Jfr::on_vm_start()
 121 #define TRACE_INITIALIZE() Jfr::on_vm_init()
 122 #define TRACE_ALLOCATION(obj, size, thread) ObjectSampleAssistance osa(obj, size, thread);
 123 #define TRACE_WEAK_OOPS_DO(is_alive, f) LeakProfiler::oops_do(is_alive, f)
 124 #define TRACE_VM_EXIT() Jfr::on_vm_shutdown();
 125 #define TRACE_VM_ERROR() Jfr::on_vm_shutdown(true);
 126 #define TRACE_DEFINE_KLASS_TRACE_ID_OFFSET \
 127   static ByteSize trace_id_offset() { return in_ByteSize(offset_of(InstanceKlass, _trace_id)); }
 128 #define TRACE_KLASS_TRACE_ID_OFFSET InstanceKlass::trace_id_offset()
 129 #define TRACE_DEFINE_THREAD_TRACE_DATA_OFFSET \
 130   static ByteSize trace_data_offset() { return in_ByteSize(offset_of(Thread, _trace_data)) ;}
 131 #define TRACE_THREAD_TRACE_DATA_OFFSET Thread::trace_data_offset()
 132 #define TRACE_DEFINE_THREAD_DATA_WRITER_OFFSET \
 133   static ByteSize java_event_writer_offset() { return in_ByteSize(offset_of(TRACE_DATA, _java_event_writer)); }
 134 #define TRACE_THREAD_DATA_WRITER_OFFSET \
 135   TRACE_DATA::java_event_writer_offset() + TRACE_THREAD_TRACE_DATA_OFFSET
 136 #define TRACE_DEFINE_THREAD_ID_OFFSET \
 137   static ByteSize trace_id_offset() { return in_ByteSize(offset_of(TRACE_DATA, _trace_id)); }
 138 #define TRACE_DEFINE_THREAD_ID_SIZE \
 139   static size_t trace_id_size() { return sizeof(traceid); }
 140 #define TRACE_THREAD_TRACE_ID_OFFSET TRACE_DATA::trace_id_offset()
 141 #define TRACE_THREAD_TRACE_ID_SHIFT 8
 142 #define TRACE_THREAD_TRACE_ID_SIZE TRACE_DATA::trace_id_size()
 143 #define TRACE_TIME_METHOD JfrTraceTime::time_function()
 144 #define TRACE_TEMPLATES(template) \
 145    template(jdk_jfr_internal_JVM,          "jdk/jfr/internal/JVM")
 146 
 147 #define TRACE_INTRINSICS(do_intrinsic, do_class, do_name, do_signature, do_alias)                            \
 148   do_intrinsic(_counterTime,        jdk_jfr_internal_JVM, counterTime_name, void_long_signature, F_SN)       \
 149     do_name(     counterTime_name,                             "counterTime")                                \
 150   do_intrinsic(_getClassId,         jdk_jfr_internal_JVM, getClassId_name, class_long_signature, F_SN)       \
 151     do_name(     getClassId_name,                              "getClassId")                                 \
 152   do_intrinsic(_getEventWriter,   jdk_jfr_internal_JVM, getEventWriter_name, void_object_signature, F_SN)    \
 153     do_name(     getEventWriter_name,                          "getEventWriter")                             \
 154 
 155 #define TRACE_HAVE_INTRINSICS
 156 
 157 extern "C" void JNICALL trace_register_natives(JNIEnv*, jclass);
 158 #define TRACE_REGISTER_NATIVES ((void*)((address_word)(&trace_register_natives)))
 159 
 160 #else // !INCLUDE_TRACE
 161 
 162 #define EVENT_THREAD_EXIT(thread)
 163 #define EVENT_THREAD_DESTRUCT(thread)
 164 #define TRACE_KLASS_CREATION(k, p, t)
 165 #define TRACE_KLASS_DEFINITION(k, t)
 166 
 167 #define TRACE_INIT_ID(k)
 168 #define TRACE_REMOVE_ID(k)
 169 #define TRACE_RESTORE_ID(k)
 170 
 171 #define TRACE_DATA TraceThreadData
 172 
 173 #define THREAD_TRACE_ID(thread) ((traceid)thread->osthread()->thread_id())
 174 
 175 #define TRACE_START() JNI_OK
 176 #define TRACE_INITIALIZE() JNI_OK
 177 #define TRACE_ALLOCATION(obj, size, thread)
 178 #define TRACE_WEAK_OOPS_DO(is_alive, f)
 179 #define TRACE_VM_EXIT()
 180 #define TRACE_VM_ERROR()
 181 
 182 #define TRACE_DEFINE_TRACE_ID_METHODS typedef int ___IGNORED_hs_trace_type1
 183 #define TRACE_DEFINE_TRACE_ID_FIELD typedef int ___IGNORED_hs_trace_type2
 184 #define TRACE_DEFINE_KLASS_TRACE_ID_OFFSET typedef int ___IGNORED_hs_trace_type3
 185 #define TRACE_KLASS_TRACE_ID_OFFSET in_ByteSize(0); ShouldNotReachHere()
 186 #define TRACE_DEFINE_THREAD_TRACE_DATA_OFFSET typedef int ___IGNORED_hs_trace_type4
 187 #define TRACE_THREAD_TRACE_DATA_OFFSET in_ByteSize(0); ShouldNotReachHere()
 188 #define TRACE_DEFINE_THREAD_TRACE_ID_OFFSET typedef int ___IGNORED_hs_trace_type5
 189 #define TRACE_THREAD_TRACE_ID_OFFSET in_ByteSize(0); ShouldNotReachHere()
 190 #define TRACE_THREAD_TRACE_ID_SHIFT
 191 #define TRACE_DEFINE_THREAD_ID_SIZE typedef int ___IGNORED_hs_trace_type6
 192 #define TRACE_DEFINE_THREAD_DATA_WRITER_OFFSET typedef int ___IGNORED_hs_trace_type7
 193 #define TRACE_THREAD_DATA_WRITER_OFFSET in_ByteSize(0); ShouldNotReachHere()
 194 #define TRACE_DEFINE_FLAG typedef int ___IGNORED_hs_trace_type8
 195 #define TRACE_DEFINE_FLAG_ACCESSOR typedef int ___IGNORED_hs_trace_type9
 196 #define TRACE_TEMPLATES(template)
 197 #define TRACE_INTRINSICS(do_intrinsic, do_class, do_name, do_signature, do_alias)
 198 
 199 #endif // INCLUDE_TRACE
 200 #endif // SHARE_VM_TRACE_TRACEMACROS_HPP