< prev index next >

src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp

Print this page

  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 "classfile/classLoaderData.inline.hpp"
 27 #include "classfile/javaClasses.inline.hpp"
 28 #include "classfile/symbolTable.hpp"


 29 #include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
 30 #include "jfr/utilities/jfrTypes.hpp"

 31 #include "oops/arrayKlass.inline.hpp"
 32 #include "oops/klass.inline.hpp"
 33 #include "oops/instanceKlass.inline.hpp"
 34 #include "oops/method.hpp"
 35 #include "oops/oop.inline.hpp"
 36 #include "runtime/atomic.hpp"
 37 #include "runtime/vm_version.hpp"
 38 #include "runtime/jniHandles.inline.hpp"
 39 #include "runtime/thread.inline.hpp"
 40 #include "utilities/debug.hpp"

 41 
 42  // returns updated value
 43 static traceid atomic_inc(traceid volatile* const dest) {










































 44   assert(VM_Version::supports_cx8(), "invariant");
 45   traceid compare_value;
 46   traceid exchange_value;
 47   do {
 48     compare_value = *dest;
 49     exchange_value = compare_value + 1;
 50   } while (Atomic::cmpxchg(dest, compare_value, exchange_value) != compare_value);
 51   return exchange_value;
 52 }
 53 
 54 static traceid next_class_id() {
 55   static volatile traceid class_id_counter = LAST_TYPE_ID + 1; // + 1 is for the void.class primitive
 56   return atomic_inc(&class_id_counter) << TRACE_ID_SHIFT;
 57 }
 58 
 59 static traceid next_thread_id() {
 60   static volatile traceid thread_id_counter = 0;
 61   return atomic_inc(&thread_id_counter);
 62 }
 63 
 64 static traceid next_module_id() {
 65   static volatile traceid module_id_counter = 0;
 66   return atomic_inc(&module_id_counter) << TRACE_ID_SHIFT;
 67 }
 68 
 69 static traceid next_package_id() {
 70   static volatile traceid package_id_counter = 0;
 71   return atomic_inc(&package_id_counter) << TRACE_ID_SHIFT;
 72 }
 73 
 74 static traceid next_class_loader_data_id() {
 75   static volatile traceid cld_id_counter = 0;
 76   return atomic_inc(&cld_id_counter) << TRACE_ID_SHIFT;
 77 }
 78 
 79 static bool found_jdk_internal_event_klass = false;
 80 static bool found_jdk_jfr_event_klass = false;
 81 
 82 static void check_klass(const Klass* klass) {
 83   assert(klass != NULL, "invariant");

  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 "classfile/classLoaderData.inline.hpp"
 27 #include "classfile/javaClasses.inline.hpp"
 28 #include "classfile/symbolTable.hpp"
 29 #include "classfile/systemDictionary.hpp"
 30 #include "jfr/jni/jfrJavaSupport.hpp"
 31 #include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
 32 #include "jfr/utilities/jfrTypes.hpp"
 33 #include "oops/access.inline.hpp"
 34 #include "oops/arrayKlass.inline.hpp"
 35 #include "oops/klass.inline.hpp"
 36 #include "oops/instanceKlass.inline.hpp"
 37 #include "oops/method.hpp"
 38 #include "oops/oop.inline.hpp"
 39 #include "runtime/atomic.hpp"
 40 #include "runtime/vm_version.hpp"
 41 #include "runtime/jniHandles.inline.hpp"
 42 #include "runtime/thread.inline.hpp"
 43 #include "utilities/debug.hpp"
 44 #include "utilities/exceptions.hpp"
 45 
 46 static int next_tid_offset = invalid_offset;
 47 static jclass thread_identifiers = NULL;
 48 
 49 static bool setup_thread_identifiers(TRAPS) {
 50   const char class_name[] = "java/lang/Thread$ThreadIdentifiers";
 51   Symbol * const k_sym = SymbolTable::new_symbol(class_name);
 52   assert(k_sym != NULL, "invariant");
 53   Klass * klass = SystemDictionary::resolve_or_fail(k_sym, true, CHECK_false);
 54   assert(klass != NULL, "invariant");
 55   assert(klass->is_instance_klass(), "invariant");
 56   assert(InstanceKlass::cast(klass)->is_initialized(), "invariant");
 57   const char next_tid_name[] = "nextTid";
 58   Symbol * const next_tid_symbol = SymbolTable::new_symbol(next_tid_name);
 59   assert(next_tid_symbol != NULL, "invariant");
 60   assert(invalid_offset == next_tid_offset, "invariant");
 61   if (!JfrJavaSupport::compute_field_offset(next_tid_offset, klass, next_tid_symbol, vmSymbols::long_signature(), true)) {
 62     return false;
 63   }
 64   assert(invalid_offset != next_tid_offset, "invariant");
 65   assert(thread_identifiers == NULL, "invariant");
 66   thread_identifiers = (jclass)JfrJavaSupport::global_jni_handle(klass->java_mirror(), THREAD);
 67   return thread_identifiers != NULL;
 68 }
 69 
 70 bool JfrTraceId::initialize() {
 71   static bool initialized = false;
 72   if (!initialized) {
 73     initialized = setup_thread_identifiers(JavaThread::current());
 74   }
 75   return initialized;
 76 }
 77 
 78 static traceid next_thread_id() {
 79   assert(thread_identifiers != NULL, "invariant");
 80   const oop base = JfrJavaSupport::resolve_non_null(thread_identifiers);
 81   traceid next;
 82   do {
 83     next = HeapAccess<>::load_at(base, (ptrdiff_t)next_tid_offset);
 84   } while (HeapAccess<>::atomic_cmpxchg_at(base, (ptrdiff_t)next_tid_offset, next, next + 1) != next);
 85   return next;
 86 }
 87 
 88 // returns updated value
 89 static traceid atomic_inc(traceid volatile* const dest, traceid stride = 1) {
 90   assert(VM_Version::supports_cx8(), "invariant");
 91   traceid compare_value;
 92   traceid exchange_value;
 93   do {
 94     compare_value = *dest;
 95     exchange_value = compare_value + stride;
 96   } while (Atomic::cmpxchg(dest, compare_value, exchange_value) != compare_value);
 97   return exchange_value;
 98 }
 99 
100 static traceid next_class_id() {
101   static volatile traceid class_id_counter = LAST_TYPE_ID + 1; // + 1 is for the void.class primitive
102   return atomic_inc(&class_id_counter) << TRACE_ID_SHIFT;
103 }
104 





105 static traceid next_module_id() {
106   static volatile traceid module_id_counter = 0;
107   return atomic_inc(&module_id_counter) << TRACE_ID_SHIFT;
108 }
109 
110 static traceid next_package_id() {
111   static volatile traceid package_id_counter = 0;
112   return atomic_inc(&package_id_counter) << TRACE_ID_SHIFT;
113 }
114 
115 static traceid next_class_loader_data_id() {
116   static volatile traceid cld_id_counter = 0;
117   return atomic_inc(&cld_id_counter) << TRACE_ID_SHIFT;
118 }
119 
120 static bool found_jdk_internal_event_klass = false;
121 static bool found_jdk_jfr_event_klass = false;
122 
123 static void check_klass(const Klass* klass) {
124   assert(klass != NULL, "invariant");
< prev index next >